如何使Unity为2个注册接口注入相同的实例

时间:2017-01-13 12:37:36

标签: c# multithreading dependency-injection unity-container decorator

我有一个类(Service),它接收2个参数(IClientICounter)。

我希望 Unity 为注入相同的实例(实现两个接口的Decorator)。

但是如何?

还有一件事:我希望Unity使用每个线程将相同的实例注入Service。这是,在每个线程中,每次调用container.Resolve<Service>()时,Decorator的相同实例都应注入Service

的两个参数

这是我到目前为止的代码。我只注册类型并运行,但是创建了3个Decorator类实例。在这种情况下,只有一个线程,只应创建一个Decorator实例。

您可以使用DotNetFiddle运行它:https://dotnetfiddle.net/Widget/m3PRQz

using System;
using Microsoft.Practices.Unity;

namespace ConsoleApplication1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var container = new UnityContainer();

            container.RegisterType<IClient>(new InjectionFactory(c => new Decorator(c.Resolve<Client>())));
            container.RegisterType<ICounter, Decorator>();

            container.Resolve<Service>();

            Console.WriteLine(Decorator.NumberOfInstances + " instances of Decorator have been created");
        }
    }

    public class Client : IClient
    {
    }

    public class Decorator : IClient, ICounter
    {
        public static int NumberOfInstances { get; private set; }    
        public Decorator(IClient client)
        {
            NumberOfInstances++;
        }        
    }

    public interface ICounter
    {
    }

    public interface IClient
    {
    }

    public class Service
    {
        public Service(IClient client, ICounter counter)
        {
        }    
    }
}

编辑:如果我没有使用DI,我会写这段代码。请记住,为简单起见,我不会调用任何方法。

public class Program
{
    public static void Main(string[] args)
    {
        var t1 = Task.Run(() => CreateService());
        var t2 = Task.Run(() => CreateService());
    }

    private static Service CreateService()
    {
        var decorator = new Decorator(new Client());
        return new Service(decorator, decorator);
    }
}

1 个答案:

答案 0 :(得分:1)

您可以尝试这样的事情:

每个线程注册Decorator:

container.RegisterType<Decorator>(
    new PerThreadLifetimeManager(), 
    new InjectionFactory(c => new Decorator(c.Resolve<Client>())));

将接口映射到装饰器:

container.RegisterType<ICounter, Decorator>();
container.RegisterType<IClient, Decorator>();