假设我有 3 个类,Program
、A
(具有依赖项 D1
和 D2
)和 B
(具有依赖项 D3
和 D4
)。 Program
在创建 A
的实例之前初始化一个 IOC 容器并注册一堆类型。
class Program
{
static void Main(string[] args)
{
IOC ioc = new IOC();
//register types
A a = ioc.Resolve<A>();
}
}
稍后,a
需要创建一个 B
的实例,将它的两个依赖项注入(inject)到构造函数中。
问题:a
应该如何解决B
的依赖?我被引导相信传递 IOC 容器,即将其注入(inject) A
是服务定位器模式,这是不好的。如果 B
创建了 C
及其依赖项,B
也需要注入(inject)容器,并且容器会在我的代码中乱七八糟。这听起来像是一场测试噩梦。使用全局静态听起来并没有好多少。
最佳答案
其实很简单。如果 A
需要 B
,它应该接受 B
作为构造函数参数:
public class A
{
private readonly D1 d1;
private readonly D2 d2;
private readonly B b;
public A(D1 d1, D2 d2, B b) {
this.d1 = d1;
this.d2 = d2;
this.b = b;
}
}
public class B
{
private readonly D3 d3;
private readonly D4 d4;
private readonly C c;
public B(D3 d3, D4 d4, C c) {
this.d3 = d3;
this.d4 = d4;
this.c = c;
}
}
通过这种方式,您可以递归地构建对象图,并且可以获得非常深的对象图,这完全没问题。这样,您只需要应用程序启动路径中的容器(也称为组合根)。
A
是否“稍后”需要B
,或者只是有时,或者几乎从不,这无关紧要。构建对象图应该很快,因此是否不必要地创建了 B
应该不是问题。
关于c# - 没有服务定位器的 IOC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31312816/