Unity IoC - 如何指定要使用的注册

Unity IoC - How to specify which registration to use

我有 2 个 类 实现了 IMyInterface,我们称它们为 ClassAClassB。这里的问题是ClassA还需要IMyInterface,应该是ClassB的实现。还有 ClassConsumer 应该使用 ClassAIMyInterface 并且依赖于 IMyInterface

有没有办法做类似的事情?:

var container = new UnityContainer();

//... several others registrations 

container.RegisterType<ITransactionProcessingService, ClassConsumer>();

var specialRegistrationForIMyInterface = _container.RegisterType<IMyInterface, ClassB>();
container.RegisterType<IMyInterface, ClassA>(specialRegistrationForIMyInterface);

代码示例:

public interface IMyInterface
{
    void PushToDatabase();
}

public class ClassA : IMyInterface
{
    IMyInterface _IMyInterface;
    public ClassA(IMyInterface myInterface)
    {
        _IMyInterface = myInterface;
    }

    public void PushToDatabase()
    {
        //do other stuff
        //BusinessCheck();
        //Log();
        //Cache();
        _IMyInterface.PushToDatabase();
    }
}

public class ClassB : IMyInterface
{
    public void PushToDatabase()
    {
        //Actual insert on database
    }
}

编辑 2:Progman 建议后的代码:

var container = new UnityContainer();

//... several others registrations 

container.RegisterType<IMyInterface, ClassB>("Foo");
container.RegisterType<IMyInterface, ClassA>("Bar", new InjectionConstructor(new ResolvedParameter<IMyInterface>("Foo")));


container.RegisterType<ITransactionProcessingService, ClassConsumer>(new InjectionConstructor(new ResolvedParameter<IMyInterface>("Bar")));

我得到一个错误 "No member matching data has been found."

您可以使用 InjectionConstructor 为构造函数提供附加信息。将它与 ResolveParameter 一起使用以指定要注入的特定实例。假设您有以下 classes 和接口:

public interface IMyInterface
{
    void PushToDatabase();
}

public class ClassA : IMyInterface
{
    public ClassA(IMyInterface myInterface)
    {
        Console.WriteLine("Constructor of ClassA was injected with: "+myInterface);
    }

    public void PushToDatabase()
    {
    }
}

public class ClassB : IMyInterface
{
    public void PushToDatabase()
    {
        //Actual insert on database
    }
}

public class ClassC : IMyInterface
{
    public void PushToDatabase()
    {
        //Actual insert on database
    }
}
public class ClassD : IMyInterface
{
    public void PushToDatabase()
    {
        //Actual insert on database
    }
}

有四种可能的实现。您可以注册所有这些实例,但是对于 class ClassA 您可以指定要注入的实例。

var container = new UnityContainer();

container.RegisterType<IMyInterface, ClassB>();
container.RegisterType<IMyInterface, ClassC>();
container.RegisterType<IMyInterface, ClassA>(new InjectionConstructor(new ResolvedParameter(typeof(ClassB))));
container.RegisterType<IMyInterface, ClassD>();

注册这样的类型意味着"For the class ClassA use an instance of ClassB for the IMyInterface argument."当你执行下面的代码时:

var classA = container.Resolve<ClassA>();
Console.WriteLine("Resolved to: "+classA);

var myInterface = container.Resolve<IMyInterface>();
Console.WriteLine("Resolved to: "+myInterface);

您将获得以下内容output

Constructor of ClassA was injected with: ClassB
Resolved to: ClassA
Resolved to: ClassD

如您所见,ClassA 对象注入了 ClassB 对象。您还会看到,当您请求 IMyInterface 时,您会获得最后注册的类型,在本例中为 ClassD.