我一直在阅读有关 DI 和组合根的信息。我在文章中读到只有应用程序应该有组合根,而不是库。
但是让我们假设我有一个带有一些接口及其实现的可重用包。我想将该接口绑定到实现。我认为如果用户必须自己做这一切会很麻烦。
在可重用模块中包含一个 XML DI 配置文件是否有意义,它将在组合根中使用和处理?
我一直在阅读有关 DI 和组合根的信息。我在文章中读到只有应用程序应该有组合根,而不是库。
但是让我们假设我有一个带有一些接口及其实现的可重用包。我想将该接口绑定到实现。我认为如果用户必须自己做这一切会很麻烦。
在可重用模块中包含一个 XML DI 配置文件是否有意义,它将在组合根中使用和处理?
尽管类库不应包含组合根,但您始终可以在库中包含一个工厂,为简单的用例创建默认图。您在库中的类型仍然是公开的,以便高级用户可以以自定义方式组合类型(例如,使用他们的特殊装饰器装饰某些类型)。您包含的工厂也可以参数化以支持多个基本用例。
关于 XML 配置,虽然可行,但在大多数情况下,维护使用 XML 进行 DI 配置的应用程序非常困难,因为一旦在代码中重命名了类型,XML 中的类型名称将不会自动重命名。
但是让我们假设我有一个带有一些接口及其实现的可重用包。我想将该接口绑定到实现。
为什么你的可重用包提供接口和实现?
如果您的可重用包是一个库,您可以提供具体的类。正如我在DI-Friendly Framework中所写:
库是一组可重用的类型或函数,您可以从各种应用程序中使用。应用程序代码启动与库的通信并调用它。
根据依赖倒置原则(DIP),客户端定义其依赖的抽象接口。库提供的任何接口都会违反 DIP。
另一方面,如果您希望客户端代码提供实现,您的可重用包可以提供抽象(接口或基类)。在这种情况下,包开始看起来更像一个框架,尽管那里可能有一个灰色区域。通常,在这种情况下,包不必提供接口的任何实现,或者它可以提供一些供可选使用。
可能存在一些边缘情况,即接口和(默认)实现与同一个包一起发布可能有意义,但我不认为它比 Yacoub Massad 推荐的那种默认工厂更值得保证。您可以使该 API 成为 Fluent Builder - 这是此类场景的常见模式。
如果您不希望任何人使用您的包,您可以提供所有您希望的 XML 配置文件。