如何注册命名类型映射以解析为未命名类型映射
本文关键字:类型 映射 未命名 何注册 注册 | 更新日期: 2023-09-27 18:07:24
我使用的是带有工作单元设计模式的实体框架,我的类结构如下:
public interface IUnitOfWork
{
void Save();
}
public class MyContext : ObjectContext, IUnitOfWork
{
public void Save()
{
SaveChanges();
}
}
然后我将MyContext类型映射注册为:
IUnityContainer unityContainer = new UnityContainer()
.RegisterType<MyContext>(new ContainerControlledLifetimeManager());
我知道如果我做了以下事情:
unityContainer.RegisterType<IUnitOfWork, MyContext>();
IUnitOfWork unitOfWork1 = unityContainer.Resolve<IUnitOfWork>();
IUnitOfWork unitOfWork2 = unityContainer.Resolve<IUnitOfWork>();
那么unitOfWork1
将是与unitOfWork2
相同的MyContext
实例,因为IUnitOfWork
映射到MyContext
,后者是容器控制的实例。
然而,如果我这样做:
unityContainer.RegisterType<IUnitOfWork, MyContext>("MyUnitOfWork");
IUnitOfWork unitOfWork1 = unityContainer.Resolve<IUnitOfWork>("MyUnitOfWork");
IUnitOfWork unitOfWork2 = unityContainer.Resolve<IUnitOfWork>("MyUnitOfWork");
然后unitOfWork1
和unitOfWork2
解析为MyContext
的两个不同实例,这对我来说没有任何意义,因为它们都映射到MyContext,它仍然是一个容器控制的实例。似乎在命名映射时,它们不会以相同的方式解析第二个类型参数。
我之所以需要命名类型映射,是因为我有多个不同的ObjectContext
,它们都实现了IUnitOfWork
,所以定义全局IUnitOfWork
类型映射是错误的。
我的问题很简单,如何在使用命名类型映射的同时仍然保留第一个实现的功能。
注意:实际上,我在实际实现中使用了PerResolveLifetimeManager
,但是ContainerControlledLifetimeManager
在较少的代码中突出了这一点。
编辑
根据我和Daniel Hilgarth的谈话。
我通过更改具有IUnitOfWork
依赖属性的类的注册来解决问题。
以前它是沿着以下路线:
unityContainer.RegisterType<Service>(new InjectionConstructor(new ResolvedParameter<IUnitOfWork>("MyUnitOfWork")));
然而,我没有解决一个名为IUnitOfWork
的问题,而是采用了一种不同的方法,而是直接解决了实现:
unityContainer.RegisterType<Service>(new InjectionConstructor(new ResolvedParameter<MyContext>()));
感谢Daniel和TheCodeKing解释命名注册的目的:(
只需传递生存期管理器:
unityContainer.RegisterType<IUnitOfWork, MyContext>(
"MyUnitOfWork", new ContainerControlledLifetimeManager());
原因:
您已将MyContext
的未命名实例注册为容器控制的实例,而不是命名的。
ContainerControlledLifetimeManager
强制执行一个singleton,因此您总是得到相同的实例。要使用解析单例的命名实例,您需要。
unityContainer.RegisterType<IUnitOfWork, MyContext>
("MyUnitOfWork", new ContainerControlledLifetimeManager());
IUnitOfWork unitOfWork1 = unityContainer.Resolve<IUnitOfWork>("MyUnitOfWork");
IUnitOfWork unitOfWork2 = unityContainer.Resolve<IUnitOfWork>("MyUnitOfWork");