当需要多个相同类型的实例时,DI与Uni​​ty

Eri*_*k Z 9 c# dependency-injection unity-container

我需要帮助.我使用Unity作为我的容器,我想在构造函数中注入两个相同类型的不同实例.

class Example
{
   Example(IQueue receiveQueue, IQueue sendQueue) {}
}
Run Code Online (Sandbox Code Playgroud)

....和IQueue在我的MessageQueue类中实现....

class MessageQueue : IQueue
{
    MessageQueue(string path) {}
}
Run Code Online (Sandbox Code Playgroud)

如何将两个不同的MessageQueue实例注入我的Example类?要使用不同的路径创建的每个MessageQueue实例.

Ran*_*ica 7

有很多方法可以实现您想要的结果(由多个答案证明).以下是使用命名注册(没有属性)的另一种方法:

IUnityContainer container = new UnityContainer();

container.RegisterType<IQueue, MessageQueue>("ReceiveQueue", 
    new InjectionConstructor("receivePath"));

container.RegisterType<IQueue, MessageQueue>("SendQueue",
    new InjectionConstructor("sendPath"));

container.RegisterType<Example>(
    new InjectionConstructor(
        new ResolvedParameter<IQueue>("ReceiveQueue"),
        new ResolvedParameter<IQueue>("SendQueue")));

Example example = container.Resolve<Example>();
Run Code Online (Sandbox Code Playgroud)

这种方法的缺点是如果更改了Example构造函数,那么还必须修改注册代码以匹配.此外,错误将是运行时错误,而不是更优选的编译时错误.

您可以将上述内容与InjectionFactory结合使用,以手动调用构造函数以进行编译时检查:

IUnityContainer container = new UnityContainer();

container.RegisterType<IQueue, MessageQueue>("ReceiveQueue",
    new InjectionConstructor("receivePath"));

container.RegisterType<IQueue, MessageQueue>("SendQueue",
    new InjectionConstructor("sendPath"));

container.RegisterType<Example>(new InjectionFactory(c =>
    new Example(c.Resolve<IQueue>("ReceiveQueue"),
                c.Resolve<IQueue>("SendQueue"))));

Example example = container.Resolve<Example>();
Run Code Online (Sandbox Code Playgroud)

如果您使用的是组合根,那么魔术字符串("ReceiveQueue"和"SendQueue")的使用将仅限于一个注册位置.


Ere*_*mez 3

您可以使用名称注册两个实例:

myContainer.RegisterInstance<IQueue>("ReceiveQueue", myReceiveMessageQueue);
myContainer.RegisterInstance<IQueue>("SendQueue", mySendMessageQueue);
Run Code Online (Sandbox Code Playgroud)

然后你应该能够通过名称解析,但它需要使用属性Dependency

class Example
{
    Example([Dependency("ReceiveQueue")] IQueue receiveQueue, 
            [Dependency("SendQueue")] IQueue sendQueue) {
   }
}
Run Code Online (Sandbox Code Playgroud)

或注入 Unity 容器,然后解析构造函数中的实例:

class Example
{
    Example(IUnityContainter container) 
    {
        _receiveQueue = container.Resolve<IQueue>("ReceiveQueue");
        _sendQueue = container.Resolve<IQueue>("SendQueue");
    }
}
Run Code Online (Sandbox Code Playgroud)