2011-09-02 88 views
0

我使用实体框架与工作设计模式的单位,我的阶级结构如下:如何注册一个名为类型映射解决的无名类型映射

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将与MyContext实例相同unitOfWork2,因为IUnitOfWork映射到MyContext,这是一个容器控制的实例。

然而,如果不是我这样做:

unityContainer.RegisterType<IUnitOfWork, MyContext>("MyUnitOfWork"); 
IUnitOfWork unitOfWork1 = unityContainer.Resolve<IUnitOfWork>("MyUnitOfWork"); 
IUnitOfWork unitOfWork2 = unityContainer.Resolve<IUnitOfWork>("MyUnitOfWork"); 

然后unitOfWork1MyContext,这没有任何意义,我unitOfWork2决心两种不同的情况下,因为它们都地图MyContext,这是仍是一个容器控制的实例。看起来,映射命名时,它们不以相同的方式解析第二个类型参数。

我需要命名类型映射的原因是因为我有多个不同的ObjectContext一切都都实现IUnitOfWork,所以这将是错误的定义一个全局IUnitOfWork类型映射。

我的问题很简单,我该如何使用命名类型映射,但仍保留第一个实现的功能。

N.B.实际上,我实际使用的是PerResolveLifetimeManager,但ContainerControlledLifetimeManager突出显示了代码少的一点。

编辑
按我与丹尼尔Hilgarth交谈。

我通过更改IUnitOfWork的依赖项属性的类的注册来解决了我的问题。

以前它是沿着线:

unityContainer.RegisterType<Service>(new InjectionConstructor(new ResolvedParameter<IUnitOfWork>("MyUnitOfWork"))); 

然而,不是解决一个名为IUnitOfWork,我采取了不同的方法,而不是直接解决了执行:

unityContainer.RegisterType<Service>(new InjectionConstructor(new ResolvedParameter<MyContext>())); 

谢谢丹尼尔和TheCodeKing用于解释命名注册的目的:)

回答

1

只需通过终身管理器:

unityContainer.RegisterType<IUnitOfWork, MyContext>(
    "MyUnitOfWork", new ContainerControlledLifetimeManager()); 

原因:
您注册MyContext无名实例作为一个容器控制的实例,而不是命名之一。

+0

这种方法的问题是,如果一个类构造函数在'MyContext'的依赖,它会得到一个实例,而如果其他类有在'IUnitOfWork'的依赖,它会得到的不同实例'MyContext',假设对IUnitOfWork具有依赖关系的类有一个'InjectionConstructor',它指定了新的ResolvedParameter (“MyUnitOfWork”)'。 – Lukazoid

+0

如果您不想要两个单独的实例,为什么您首先使用命名注册?命名注册的全部原因是在不同的环境中提供不同的实例。 –

+0

如果我有几个依赖于'IUnitOfWork'的类,在某些情况下,我希望这个'IUnitOfWork'是一个'MyContext',在其他情况下我可能希望它是另一个实现,因此我正在使用命名注册来区分要解析的“IUnitOfWork”的哪个实现。我提供的例子有些琐碎,根据我的说明,我实际上使用了'PerResolveLifetimeManager',所以我希望'IUnitOfWork'的不同实例和实现有不同的解析。 – Lukazoid

1

ContainerControlledLifetimeManager执行一个单例,所以你总是得到相同的实例。要使用解析单例的命名实例,您需要。

unityContainer.RegisterType<IUnitOfWork, MyContext> 
        ("MyUnitOfWork", new ContainerControlledLifetimeManager()); 
IUnitOfWork unitOfWork1 = unityContainer.Resolve<IUnitOfWork>("MyUnitOfWork"); 
IUnitOfWork unitOfWork2 = unityContainer.Resolve<IUnitOfWork>("MyUnitOfWork"); 
+0

如果你看到我对Daniel Hilgarth的回应,你会明白为什么我相信这种方法是不可取的。 – Lukazoid

+0

对不起,我不清楚问题是什么。如果你想要一个单身人士,可以使用'ContainerControlledLifetimeManager',如果你不需要的话。使用命名实例来区分您想要新实例还是现有实例。您可以在解析时始终使用依赖项替代。也许把问题简化成你真正想做的事情? – TheCodeKing

+0

与我所做的例子相反,我没有使用'ContainerControlledLifetimeManager',我只是用它来给出一个代码示例。在我的实现中,我使用了'PerResolveLifetimeManager'。如果我有一个类,它有两个依赖项,每个依赖于'IUnitOfWork',我想将它们解析为'MyContext'的同一个实例。我是通过使用'InjectionConstructor'和'new ResolvedParameter (“MyUnitOfWork”)' – Lukazoid