c# - 没有服务定位器的 IOC

标签 c# oop design-patterns inversion-of-control service-locator

假设我有 3 个类,ProgramA(具有依赖项 D1D2)和 B(具有依赖项 D3D4)。 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/

相关文章:

c# - 将 gridview 导出到 Excel 时无法识别阿拉伯字符

java - 通过另一个方法获取方法的局部变量

c# - 当有单独的数据模型时,如何从存储库返回域对象?

java - 亲子结构的设计模式

django - NextJS 使用 Django API - 如何选择最佳模式

c# - 查找以开头的字符串的索引

c# - 我可以使用 Microsoft Lync API 与 Communicator 2007/2007 R2 通信吗?

c# - C# 函数参数中的方括号语法?

php - 使用 php 进行有效的表单处理

oop - 模型/ View 分离