组合根(Composition Root)
本文是组合根(Composition Root)模式的总结描述。
构造函数注入模式易于理解,直到出现后续问题:
我们该在哪里组合对象图?
很容易理解,每个类都应通过其构造函数来要求其依赖关系,但这将编写具有依赖关系的类的责任推给了第三方。那应该在哪里?
在我看来,大多数人都渴望尽早组合,但正确的答案是:
尽可能靠近应用程序的入口点。
这个地方被称为应用的组合根,定义如下:
组合根(Composition Root)是应用中模块组合在一起的(最佳)唯一位置。
这意味着所有的应用代码都只依赖于构造函数注入(或其他注入模式),但从不进行组合。只有在应用的入口点,才能最终组合整个对象图。
合适的切入点取决于框架:
- 在控制台应用,这是 main 方法
- 在 ASP.NET MVC 应用中,它是 global.asax 以及自定义的 IControllerFactory
- 在 WPF 应用中,它是 Application.OnStartup 方法
- 在 WCF 应用中,它是自定义 ServiceHostFactory
- 等等。
Composition Root 是一个应用基础结构组件。
只有应用拥有 Composition Roots。库和框架不应该有。
Composition Root 可以用 Poor Man's DI Pure DI 实现,同时也是使用 DI Container 的(唯一)合适位置。
DI 容器只能从组合根引用。所有其他模块都不应该引用该容器。
使用 DI 容器通常是一个不错的选择。在这种情况下,应该完全从组合根中使用注册解析发布(Register Resolve Release pattern)模式来应用它。