我正在试图掌握IoC容器(目前专门针对Unity),并且在预先注入所有依赖项的概念上有点挣扎。
我的问题特别与一个具有构造函数参数的类有关,该参数的值在我最初在容器中注册类型时是未知的。
这里有一个小片段,应该说明我在说什么。
class Class1
{
IUnityContainer uContainer;
public Class1()
{
uContainer = new UnityContainer();
uContainer.RegisterType<IRepo, Repo>(new ContainerControlledLifetimeManager()));
Class2 cls2 = uContainer.Resolve<Class2>();
cls2.DoSomething();
}
}
class Class2
{
IRepo _repo;
public Class2(IRepo p_repo)
{
_repo = p_repo;
}
public void DoSomething()
{
IType2 typ2 = new Type2(_repo.SomeDataRetrieved());
Class3 cls3 = new Class3(_repo, typ2);
}
}
class Class3
{
IRepo _repo;
IType2 _type2;
public Class3(IRepo p_repo, IType2 p_type2)
{
_repo = p_repo;
_type2 = p_type2;
}
}
我可以在Class1中设置容器,并使用UnityContainer将Repo注入Class2。在Class2中,针对Repo的一些查找返回了Type2的实例,该实例只能在Class2中实例化。然后我需要将Repo传递给Class3以及Type2创建的新对象。
问题是双重的:
就目前而言,我可以使用容器将依赖项注入Class2,但是对于Class3,我需要创建新实例或使用2到3的构造函数注入,这让我想知道为什么我使用Container然后无论如何,我不得不求助于手动注射。
那么,我如何在容器中注册Class3,以便在实例化时,我注入在开头的容器中注册的repo的单例以及在DoSomething中创建的Type2的实例。 / p>
提前感谢您的帮助。
答案 0 :(得分:0)
我看到了关于你的方法的多个方面:
program
中,或等效的,忽略了这个评论。Func<IType2, Class3>
传递给它的构造函数,并从Class2中调用该工厂来获取Class3
实例。这是一个例子:container.RegisterType<Func<Type2, Class3>>(
new InjectionFactory(c =>
new Func<Type2, Class3>(type2 =>
c.Resolve<Class3>(
new InjectionConstructor(
new ResolvedParameter<IRepo>(),
type2)))));
注意:尚未测试那个代码,但我做了类似的事情。
答案 1 :(得分:0)
除了Tipx的答案,在进行依赖注入时,您不希望您的类直接创建其他类。
public void DoSomething()
{
IType2 typ2 = new Type2(_repo.SomeDataRetrieved());
Class3 cls3 = new Class3(_repo, typ2);
}
这会将class2
与Type2
和Class3
联系起来,如果这三个关闭的话可能没问题,可以交换其中任何一个,但通常在某个时候你想换Type2
代替OverchargedType2Plus
或Type2Mock
。这就是抽象工厂的用途:给Class2
一些可以创建Type2
的东西。
interface IType2Factory
{
IType2 Create( Data theData );
}
class Type2Type2Factory : IType2Factory
{
public IType2 Create( Data theData ) => new Type2( theData );
}
(如果Type2
需要进一步的依赖关系,请参阅this answer)
然后,将IType2Factory
提交给Class2
:
class Class2
{
private readonly IRepo _repo;
private readonly IType2Factory _type2Factory;
public Class2( IRepo repo, IType2Factory type2Factory )
{
_repo = repo;
_type2Factory = type2Factory;
}
public void DoSomething()
{
var typ2 = _type2Factory.Create( _repo.SomeDataRetrieved() );
}
}
当这一天到来且您需要OverchargedType2Plus
时,请创建一个IType2Factory
实施并对其进行注册,并观看Class2
使用新的Type2
变体,而不知道它存在,更不用说要求任何改变了。