Unity IoC - 如何指定要使用的注册
Unity IoC - How to specify which registration to use
我有 2 个 类 实现了 IMyInterface
,我们称它们为 ClassA
和 ClassB
。这里的问题是ClassA
还需要IMyInterface
,应该是ClassB
的实现。还有 ClassConsumer
应该使用 ClassA
(IMyInterface
并且依赖于 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
.
我有 2 个 类 实现了 IMyInterface
,我们称它们为 ClassA
和 ClassB
。这里的问题是ClassA
还需要IMyInterface
,应该是ClassB
的实现。还有 ClassConsumer
应该使用 ClassA
(IMyInterface
并且依赖于 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
.