【问题标题】:Dependency injection, composition root, and entry points依赖注入、组合根和入口点
【发布时间】:2020-05-02 16:12:41
【问题描述】:

我花了很多时间阅读这些文章(以及许多其他文章):

我仍在尝试围绕 DI 以及“连接依赖项”的概念以及 IoC 容器的“自动连接”功能。

我想我了解依赖注入和控制反转的理论,并且我从 2016 年开始实现了此处显示的示例(我更新了代码以使用 PSR-11 并消除了对 container-interop 包的需要):

容器示例的应用程序显示在 GitHub 链接:https://github.com/sitepoint-editors/Container

请注意,虽然此示例使用 PHP,但我试图独立于语言来理解 DI 的细节,因此欢迎使用任何语言。

有人可以解释手动连接依赖项和使用容器的自动连接功能之间的区别吗? SitePoint 文章简要提到了更高级的容器添加了自动连接功能,暗示该示例尚未包含此功能。有人可以解释一下 GitHub 页面上显示的应用程序,以及它与核心 DI 和 IoC 概念的关系,例如 Composition Root。

【问题讨论】:

    标签: dependency-injection inversion-of-control


    【解决方案1】:

    有人可以解释手动连接依赖项和使用容器的自动连接功能之间的区别吗?

    纯 DI 是在不使用 DI 容器的情况下应用 DI 的做法。这意味着您可以通过使用编程语言的new 构造更新对象来构建对象图。例如,请参阅 C# 中的这个示例(来自 Mark 的书 Dependency Injection Principles, Practices, and Patternslisting 12.2):

    new HomeController(
        new ProductService(
            new SqlProductRepository(
                new CommerceContext(connectionString)),
            new AspNetUserContextAdapter()));
    

    根据那本书,自动接线是:

    利用编译器和[运行时环境]提供的类型信息,从抽象和具体类型之间的映射自动组合对象图的能力。(参见12.1.2) p>

    换句话说,使用 DI 容器,您将能够“仅”告诉容器您的类型,它会找出一个类型具有哪些依赖项,并将能够将该类型与其依赖项“连接”起来.

    考虑到前面的例子,清单 12.3 展示了如何只需要在容器中指定抽象和具体类型之间的映射:

    var container = new AutoWireContainer();
    
    container.Register(typeof(IUserContext), typeof(AspNetUserContextAdapter));
    container.Register(typeof(IProductRepository), typeof(SqlProductRepository));
    container.Register(typeof(IProductService), typeof(ProductService));
    container.Register(typeof(CommerceContext), () => new CommerceContext(connectionString));
    

    当您请求HomeController 时,容器知道如何构建整个图表。

    SitePoint 文章简要提到了更高级的容器添加了自动布线功能

    对我来说,自动连线是将库变成 DI 容器的原因。如果至少不支持 Auto-Wiring,则不能称为 DI Container。

    【讨论】:

    • 我仍然对“布线”这个词感兴趣:它是指手动或自动创建对象图的行为吗?这些代码摘录中显示的对象图是否按字面意思实现为独立对象的嵌套级联?为了使该对象图开始解析,必须手动提供最内部的依赖项以及必要的依赖项,例如第一个示例中的connectionStringconnectionString 将类似于没有其他依赖项的根依赖项。这大致正确吗?
    • “连线”与“组合”对象图相同;它指的是图形的创建,无论是手动还是使用 DI 容器。
    • 在书中的示例中,connectionStringstring 类型,它是从配置文件中提取的。这是一个简单的配置值。字符串没有自己的依赖项。但是,我们不会将其称为“根”依赖项。我们通常考虑没有消费者的类的“根”。这个字符串是一个“叶子”。
    • 这很公平。我会看看我是否可以提出一个新问题来解决这个问题。
    • 我想我已经通过阅读 Mark 的书回答了我的大部分问题。虽然它已针对 .Net 进行了调整,但其原则已经很好地适用于通用应用程序。事实证明,我对软件架构的了解比我预期的要多得多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-16
    • 2012-03-15
    • 2010-10-06
    • 1970-01-01
    • 2013-03-28
    • 2012-12-23
    • 1970-01-01
    相关资源
    最近更新 更多