Ninject的资源库工厂

时间:2014-03-11 09:27:03

标签: c# entity-framework asp.net-mvc-4 ninject

在我的应用程序中,我使用存储库进行CRUD操作。在所有实体中,有些实体根本不应该是可删除的,某些实体(实现ISoftDeletable)只是软删除,而某些实体(实现IPermanentDeletable)可以永久删除。 (我正在关注这篇文章的回答Generic Repository with Soft Delete Feature

我有3个存储库,彼此继承如下

BaseRepository : IRepository

SoftDeleteRepository : BaseRepository, ISoftDeleteRepository

PermanentDeleteRepository : BaseRepository, IPermanentDeleteRepository

我的问题是,我不想为不同类型的每个实体(如

)进行单独绑定
kernel.Bind(typeof(IRepository<Company>)).To(typeof(BaseRepository<Company>));
kernel.Bind(typeof(IRepository<Country>)).To(typeof(PermanentDeleteRepository<Country>));
kernel.Bind(typeof(IRepository<Contact>)).To(typeof(SoftDeleteRepository<Contact>));

但相反,我想以某种方式使它成为IRepository的所有绑定进入工厂并根据其泛型参数所采用的实体的类型实例化存储库,并将其注入控制器。

有可能实现这个目标吗?

1 个答案:

答案 0 :(得分:3)

所以这就是你在向消费者注入IRepository<XYZ>时如何实现它的目的:

public interface ISoftDeletable
{
}

public interface IPermanentDeleteable
{
}

public interface IRepository<TEntity>
{
}

public class PermanentDeletableRepository<TEntity> : IRepository<TEntity>
    where TEntity : IPermanentDeleteable
{
}

public class SoftDeletableRepository<TEntity> : IRepository<TEntity>
    where TEntity : ISoftDeletable
{
}

public class RepositoryModule : NinjectModule
{
    public override void Load()
    {
        this.Bind(typeof(IRepository<>))
            .To(typeof(PermanentDeletableRepository<>))
            .When(IsRequestForRepositoryOfEntityImplementing<IPermanentDeleteable>);

        this.Bind(typeof(IRepository<>))
            .To(typeof(SoftDeletableRepository<>))
            .When(IsRequestForRepositoryOfEntityImplementing<ISoftDeletable>);
    }

    public static bool IsRequestForRepositoryOfEntityImplementing<TInterface>(IRequest request)
    {
        Type entityType = GetEntityTypeOfRepository(request.Service);
        return ImplementsInterface<TInterface>(entityType);
    }

    public static Type GetEntityTypeOfRepository(Type repositoryType)
    {
        // target.Type must be IRepository<"AnyEntity">
        return repositoryType.GetGenericArguments().Single();
    }

    public static bool ImplementsInterface<TInterface>(Type type)
    {
        return typeof(TInterface).IsAssignableFrom(type);
    }
}

我通过单元测试验证了它的工作原理:

    public class SomeSoftDeletableEntity : ISoftDeletable
    {
    }

    [Fact]
    public void RepositoryBinding()
    {
        var kernel = new StandardKernel();
        kernel.Load<RepositoryModule>();

        IRepository<SomeSoftDeletableEntity> repository = kernel.Get<IRepository<SomeSoftDeletableEntity>>();

        repository.Should().BeOfType<SoftDeletableRepository<SomeSoftDeletableEntity>>();
    }