entity-framework - 使用Unity,如何注册泛型的类型映射?

标签 entity-framework unity-container repository-pattern separation-of-concerns

我正在尝试实现repository solution for Entity Framework,但是在使用Unity注册包含泛型的类型时遇到了麻烦。

鉴于:

    // IRepository interface
    public interface IRepository<TEntity>
    {
        // omitted for brevity
    }

    // Repository implementation
    public class Repository<TEntity, TContext> : IRepository<TEntity>, IDisposable 
            where TEntity : class
            where TContext : DbContext
    {
        // omitted for brevity
    }

    // service layer constructor
    public MyServiceConstructor(IRepository<Account> repository)
    {
        _repository = repository;
    }

我需要注册IRepository到Repository的类型映射。但是我无法使用此类映射的Unity语法。

我没有运气就尝试了以下方法:
container.RegisterType<IRepository<>, typeof(Repository<,>)>();
container.RegisterType<typeof(IRepository<>), Repository<,>>();

编辑

基于@Steven响应,我现在有以下实现:
// UnityRepository implementation   
public class UnityRepository<TEntity> : Repository<TEntity, MyDbContextEntities>
        where TEntity : class
{
    public UnityRepository() : base(new MyDbContextEntities()) { }
}

// Unity bootstrapper
container.RegisterType(typeof(IRepository<>), typeof(UnityRepository<>));

最佳答案

您正在尝试执行以下操作:

container.RegisterType(typeof(IRepository<>), typeof(Repository<,>));

这通常是可行的,但在这种情况下将无法解决问题,因为IRepository<TEntity>有一个通用参数,Repository<TEntity, TContext>有两个通用参数,而Unity(显然)无法猜测TContext应该填写哪种类型。

您需要的是:
container.RegisterType(
    typeof(IRepository<>),
    typeof(Repository<, MyDbContextEntities>));

换句话说,您想提供Repository<TEntity, TContext>作为部分开放的通用类型(填充一个参数)。不幸的是,C#编译器不支持此功能。

但是,即使C#支持此功能,Unity也不支持部分开放的泛型类型。实际上,大多数IoC库eworks都不支持此功能。对于确实支持它的那个one library,您仍然必须做以下(讨厌的事情)来创建部分开放的泛型类型:
Type myDbContextEntitiesRepositoryType =
    typeof(Repository<,>).MakeGenericType(
        typeof(Repository<,>).GetGenericParameters().First(),
        typeof(MyDbContextEntities));

有一个简单的技巧可以解决此问题:使用一种泛型类型定义派生类:
// Special implementation inside your Composition Root
public class UnityRepository<TEntity> : Repository<TEntity, MyDbContextEntities>
        where TEntity : class
{
    public UnityRepository([dependencies]) : base([dependencies]) { }
}

现在,我们可以轻松注册此开放通用类型:
container.RegisterType(typeof(IRepository<>), typeof(UnityRepository<>));

关于entity-framework - 使用Unity,如何注册泛型的类型映射?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18880526/

相关文章:

entity-framework - Entity Framework 代码首先使用级联删除

unity-container - 将 Unity 升级到 5.11

c# - 为什么我的自定义调用处理程序没有被调用?

使用 Unity 2.0 http 模块时,ASP.NET 4.0 GridView OnRowEditing 事件不会触发

android - RxJava2 中的存储库模式

c# - 在 Entity framework6 Repository 模式中限制用户只能访问他/她的实体

c# - 使用与表相同类型的 View

c# - Entity Framework 将数千个对象传输到 Elastic Search

asp.net-mvc - MVC5 Entity Framework 的问题

sql - 临时数据和存储库模式