10

我正在尝试为实体框架实现存储库解决方案,但在使用 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<>));
4

1 回答 1

17

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

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 都不支持这一点。对于支持它的那个,您仍然需要执行以下(讨厌的事情)来创建部分开放的泛型类型:

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<>));
于 2013-09-18T19:33:06.200 回答