编程

组合根(Composition Root)

519 2024-03-07 19:58:00

本文是组合根(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)模式来应用它。