我认为社区对于 Composition Root 的外观并没有完全一致。
例如,您可以通过练习Pure Dependency Injection (Pure DI) 手动连接您的对象,或者您可以使用依赖注入容器并手动注册您的映射,或者您可以使用依赖注入容器并围绕类和接口名称创建一些约定实现所谓的约定优于配置。或者您可以混合使用这三种方法。
另一个例子:你可以选择在 Composition Root 中连接所有内容(我认为更好的选择),或者你可以选择为每个组件(例如 .NET 中的类库)设置一个“小型 Composition Root”系统,然后将这些根连接到“主合成根”中。
根据您选择的方法,Composition Root 的知识会有所不同。
例如,如果您使用 Pure DI 并且只有一个 Composition Root,那么 Composition Root 将需要非常了解应用程序。
另一方面,如果您遵循约定优于配置的方法,那么关于哪些类应该映射到哪些接口的一些知识将分布在各处(在类和接口名称等内部)。
根据我的经验,对于任何足够大的应用程序,具有单个组合根的 Pure DI + 是最佳选择。这为您提供了一个了解应用程序的中心位置,并使您的Composition Root navigable。
这意味着 Composition Root 的责任非常大。我不确定我们是否可以称它为上帝的对象。我认为创造这个词的背景是不同的。
我不会说合成根“太多”了。虽然它做了很多,我认为它应该。如果您像我一样,那么您需要一个可以导航和了解您的应用程序的位置。
要分解您的 Composition Root,您可以将其拆分为多个方法。我有时会在 C# 中创建一个部分类(多个文件中的单个类)并将相关方法放入同一个文件中。
虽然应用图是一个图,但是如果它是一棵树,分解起来会容易得多。我尽力使图树状。如果两个对象需要类似的依赖关系,我会尝试为它们提供这种依赖关系的不同实例,以保持图的树状结构。
我已经写了一篇关于这个主题的文章,你可以阅读它here。
Here 也是另一篇文章,提供了关于 Composition Root 职责的一些观点。