如何注册命名类型映射以解析为未命名类型映射

本文关键字:类型 映射 未命名 何注册 注册 | 更新日期: 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");

然后unitOfWork1unitOfWork2解析为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");