Entity framework 使用Unity,如何为泛型注册类型映射?
我正在尝试实现一个,但是我在使用Unity注册包含泛型的类型时遇到了问题 鉴于:Entity framework 使用Unity,如何为泛型注册类型映射?,entity-framework,unity-container,repository-pattern,separation-of-concerns,Entity Framework,Unity Container,Repository Pattern,Separation Of Concerns,我正在尝试实现一个,但是我在使用Unity注册包含泛型的类型时遇到了问题 鉴于: // IRepository interface public interface IRepository<TEntity> { // omitted for brevity } // Repository implementation public class Repository<TEntity, TContext> :
// 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;
}
//i存储接口
公共接口假定
{
//为简洁起见省略
}
//存储库实现
公共类存储库:IRepository,IDisposable
地点:班级
其中TContext:DbContext
{
//为简洁起见省略
}
//服务层构造函数
公共MyServiceConstructor(IRepository存储库)
{
_存储库=存储库;
}
我需要注册IRepository到存储库的类型映射。但是我在这种映射的统一语法方面遇到了问题
我尝试了以下方法,但没有成功:
container.RegisterType<IRepository<>, typeof(Repository<,>)>();
container.RegisterType<typeof(IRepository<>), Repository<,>>();
container.RegisterType();
container.RegisterType();
编辑
根据@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<>));
//UnityRepository实现
公共类UnityRepository:存储库
地点:班级
{
public UnityRepository():基(新的MyDbContexties()){}
}
//统一引导器
容器注册类型(typeof(IRepository),typeof(UnityRepository));
您正在尝试执行以下操作:
container.RegisterType(typeof(IRepository<>), typeof(Repository<,>));
换句话说,您希望将存储库
作为部分打开的泛型类型提供(只填写一个参数)。不幸的是,C#编译器不支持这一点
但即使C#确实支持这一点,Unity也不支持部分开放泛型类型。事实上,大多数国际奥委会图书馆eWork都不支持这一点。对于确实支持它的类型,您仍然必须执行以下操作(讨厌的事情)来创建部分打开的泛型类型:
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<>));
键入MyDbContextentiesRepositoryType=
typeof(存储库).MakeGenericType(
typeof(Repository).GetGenericParameters().First(),
typeof(mydbcontextenties));
不过,有一个简单的技巧可以解决这一问题:使用一个泛型类型定义派生类:
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<>));
//组合根目录中的特殊实现
公共类UnityRepository:存储库
地点:班级
{
公共UnityRepository([dependencies]):基([dependencies]){}
}
现在,我们可以轻松注册此开放泛型类型:
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<>));
container.RegisterType(typeof(IRepository)、typeof(UnityRepository));
谢谢!请看我的编辑上面。您建议将UnityRepository
实现放在compositionroot/unity引导程序中,还是放在存储库层中的一个单独的类文件中?我现在有它在后者。当你说publicUnityRepository([dependencies]):base([dependencies]){}
,我想你的意思是public UnityRepository(TEntity entity):base(new mydbcontexties()){}
。我目前将它设置为public UnityRepository(TEntity entity):base(new mydbcontextities()){}
,它工作得很好,我通常在bootstrapper类中创建它们作为私有嵌套类。@MarkErasmus:因为UnityRepository
只是一个帮助类,所以您通常希望它具有与原始类相同的构造函数参数。这样,您仍然可以让容器为您进行布线。因此我希望UnityRepository
接受mydbcontextities
,或者在您的情况下可能根本没有参数。传递一个tenty
是很奇怪的,因为您根本不应该使用容器来创建实体。有设计时配置的解决方案吗?XML?@IssaFram:是的,解决方案很简单:不要通过XML配置容器。不,说真的,不要这样做。