在依赖注入的背景下,什么是组合根?

87
我正在探索依赖注入,而术语组合根随处可见。那么它是什么意思?

1
请参阅 DIPP&P 中的 理解组合根 - Steven
2个回答

86
组合根是应用程序中单一的位置,用于组合对象图,使用依赖注入容器(虽然如何完成这一点并不重要,可以使用容器或手动使用纯DI)。只应该有一个地方进行此操作,并且您的容器不应在组合根之外使用。
引用下面链接中的一个答案:
实际上,这意味着您应该在应用程序的根处配置容器。
在桌面应用程序中,这将在Main方法(或非常接近它)中完成;在ASP.NET(包括MVC)应用程序中,这将在Global.asax中完成;在WCF中,这将在ServiceHostFactory中完成等等。
关于这个问题,这里有一个很好的答案这里解释得更详细。
另请参阅这个答案

在像 PHP 框架这样的 Web 应用中,组合根应该是 index.php 吗? - CMCDragonkai
@CMCDragonkai 尽管我对 PHP 不太熟悉,但 index.php 并不像一个合适的放置位置。 - Oscar Mederos
或者类似于bootstrap.php的文件,它在index.php中被调用。 - CMCDragonkai
@CMCDragonkai,对于PHP MVC框架,我通常使用引导包含文件来设置依赖项。然而,如果不使用DI容器(手动进行连接时),在您已经知道将要使用哪个控制器时,在其他地方进行设置可能会很有用,这样您只需设置相关对象,否则您可能会实例化许多不会使用的对象。这不是支持惰性加载的DI容器的问题,也不是小型应用程序的问题(对于非常小的应用程序,index.php可能是一个好的位置)。只需记住只有一个CR。 - MV.
很好的解释,谢谢。但是如果注入的服务被更改了(例如在一个地方重新初始化),如何确保所有需要更新注入服务的客户端项目都是最新的? - komizo
显示剩余3条评论

8

Mark Seemann写了一篇关于组合根设计模式的优秀文章。

这篇文章中的要点是:

组合根是应用程序中(最好是)唯一的位置,用于将模块组合在一起。

只有应用程序应该具有组合根。库和框架不应该有组合根。

依赖注入容器应该仅从组合根引用。所有其他模块都不应该引用容器。

http://blog.ploeh.dk/2011/07/28/CompositionRoot/

我根据这些原则编写了自己的JavaScript依赖注入框架Di-Ninja。

https://github.com/di-ninja/di-ninja

据我所知,这是JavaScript中唯一实现组合根设计模式的框架,其文档可能是另一个很好的示例,可用于演示它的工作原理。

它适用于NodeJS、浏览器(使用Webpack或UMD/AMD)和React-Native。


一个更详细的关于组合根是什么的描述,可以在马克的书籍摘录中找到:https://freecontent.manning.com/dependency-injection-in-net-2nd-edition-understanding-the-composition-root/ - Steven

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