我正在尝试实现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<>));
答案 0 :(得分:16)
您正尝试执行以下操作:
container.RegisterType(typeof(IRepository<>), typeof(Repository<,>));
这通常会有效,但在这种情况下不会有诀窍,因为IRepository<TEntity>
有一个通用参数而Repository<TEntity, TContext>
有两个,而Unity(显然)可以&#39 ;猜猜它应该为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<>));