依赖注入、组合根和入口点

3
我花了很多时间阅读这些文章(以及许多其他文章): 我仍在努力理解 DI、"wiring up the dependencies" 和一个 IoC 容器中的 "auto wiring" 功能。我认为我理解了依赖注入和控制反转的理论,并且已经实现了这里2016年的示例(我更新了代码以使用 PSR-11 并消除了对 container-interop 包的需要)。 容器示例的应用在GitHub链接中展示:https://github.com/sitepoint-editors/Container
请注意,虽然此示例使用了PHP,但我正在尝试独立于语言理解DI的细节,因此任何语言都可以。
有人能解释一下手动连接依赖项和使用容器自动连接功能之间的区别吗?SitePoint文章简要提到,更高级的容器添加了自动连接功能,这意味着示例中不包含此功能。有人能解释一下在GitHub页面上展示的应用程序以及它如何与核心DI和IoC概念(如组合根)相关联吗?
1个回答

4
请问有人能解释一下手动连接依赖项和使用容器的自动连接功能之间的区别吗?纯DI是在不使用DI容器的情况下应用DI的做法。这意味着您通过使用编程语言的new构造函数来新建对象,从而构建对象图。例如,可以参考C#中的此示例(来自Mark的书《依赖注入原理、实践和模式》的清单12.2)。
new HomeController(
    new ProductService(
        new SqlProductRepository(
            new CommerceContext(connectionString)),
        new AspNetUserContextAdapter()));

根据该书,自动装配是指:利用编译器和运行环境提供的类型信息,通过映射抽象和具体类型来自动组合对象图的能力(参见12.1.2)。 换句话说,使用依赖注入容器,您只需告诉容器有关您的类型,它就会找出类型所需的依赖项,并能够将该类型与其依赖项“连接”起来。 考虑前面的示例,清单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容器的关键。如果它不支持至少自动装配,那么它就不能被称为DI容器。

1
“Wiring”与“组装”对象图是相同的概念;它指的是手动或使用依赖注入容器创建对象图的过程。 - Steven
谢谢,我在寻找这些词语,但是找不到。我会扩展我的问题,涉及到另一个我想提出的与此相关的点。 - Brian
1
在书中的例子中,connectionString 是一个 string 类型,它是从配置文件中获取的。这是一个简单的配置值。字符串本身没有任何依赖关系。然而,我们不会称其为“根”依赖项。通常,我们认为那些没有消费者的类是“根”。这个字符串是一个“叶子”。 - Steven
1
好的,我会看看能否整理出一个新问题来解决这个问题。 - Brian
1
我觉得通过阅读马克的书,我已经回答了大部分问题。虽然这本书是针对.Net调整的,但其中的原则适用于通用应用程序。事实证明,我对软件架构的学习远远超出了我的预期。 - Brian
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接