Dependency injection 对于DI,每个模块都有一个XML配置文件有意义吗?

Dependency injection 对于DI,每个模块都有一个XML配置文件有意义吗?,dependency-injection,inversion-of-control,compositionroot,Dependency Injection,Inversion Of Control,Compositionroot,我一直在读关于DI和组合根的书。我在文章中读到,只有应用程序才应该有合成根,而不是库 但是让我们假设我有一个可重用的包,其中包含一些接口及其实现。我希望将该接口绑定到实现。我认为,如果用户必须自己做这些事情,那将是很麻烦的 在可重用模块中包含一个XML DI配置文件(将在合成根目录中使用和处理)有意义吗?尽管类库不应包含合成根目录,但您始终可以在库中包含一个工厂,为简单用例创建默认图。库中的类型仍将是公共的,以便高级用户可以自定义方式组合类型(例如,使用其特殊的装饰器装饰某些类型)。您包含的工厂

我一直在读关于DI和组合根的书。我在文章中读到,只有应用程序才应该有合成根,而不是库

但是让我们假设我有一个可重用的包,其中包含一些接口及其实现。我希望将该接口绑定到实现。我认为,如果用户必须自己做这些事情,那将是很麻烦的


在可重用模块中包含一个XML DI配置文件(将在合成根目录中使用和处理)有意义吗?

尽管类库不应包含合成根目录,但您始终可以在库中包含一个工厂,为简单用例创建默认图。库中的类型仍将是公共的,以便高级用户可以自定义方式组合类型(例如,使用其特殊的装饰器装饰某些类型)。您包含的工厂也可以参数化以支持多个基本用例

关于XML配置,尽管它可以工作,但在大多数情况下,维护使用XML进行DI配置的应用程序非常困难,因为一旦在代码中重命名了类型,XML中的类型名称将不会自动重命名

但是让我们假设我有一个可重用的包,其中包含一些接口及其实现。我希望将该接口绑定到实现

为什么您的可重用包提供接口和实现

如果您的可重用包是一个库,那么您可以提供具体的类。我在信中写道:

库是一组可重用的类型或函数,可以从各种应用程序中使用。应用程序代码启动与库的通信并调用它

根据(DIP),客户机定义其依赖项的抽象接口。库提供的任何接口都会违反DIP

另一方面,如果您希望客户机代码提供实现,那么您的可重用包可以提供抽象(接口或基类)。在这种情况下,包开始看起来更像一个框架,尽管那里可能有一个灰色区域。通常,在这种情况下,包不必提供接口的任何实现,也可以提供一些供选择使用

在某些边缘情况下,使用同一个包提供接口和(默认)实现可能是有意义的,但我看不出它如何保证比Yacoub Massad推荐的默认工厂更多。你可以让API成为一个流畅的构建器——这是这种场景的常见模式


如果您不希望任何人使用您的软件包,您可以提供所需的所有XML配置文件。

您可能引用的文章摘自。同一本书中有一篇关于使用配置文件的文章,其中指出“使用XML作为配置机制的经验[…]他透露,这很少是最好的选择。XML往往冗长而脆弱。“你当然应该阅读该部分。@史蒂文谢谢你的回复!我一定会读到的。但假设我使用基于代码的配置,而不是XML。将这些基于代码的配置文件放在各自的模块中仍然有意义吗?并在应用程序中处理这些配置文件?请参阅,谢谢您的回复!但我希望避免手动注册工厂或其他类型的类。我正在尝试编写一个解决方案,它采用基于代码的配置文件,配置接口及其实例,并在合成根目录中自动处理它们。“你认为这是个好主意吗?”AcTijjjes,我不使用DI容器,我告诉你的工厂是一个简单的类(或静态方法),它从你的库中创建单独的类型并将它们组合在一起。让我们来看看这个概念。我不喜欢使用带有接口和相应实现类型的配置文件,原因是我以前告诉过您。代码重构工具不能处理这样的配置文件。谢谢你的回复。在过去的几天里,我读了很多你的文章。当我写这个问题时,我的意图是创建几个包,其中包含几个存储库接口和这些接口的默认实现(例如UsersRepository),我可以在一些项目中共享这些接口。但是如果我理解正确,那么提供存储库接口的具体实现是没有意义的,而只是创建接口并在我的应用程序代码中进行具体实现?@ArctiqJens相反。您可以在可重用库中发布数据库实现。我可以看出这是多么有用。但是,如果您还提供了一个接口,那么客户端代码必须引用您的库才能针对该接口编程。客户机代码现在将取决于具体的实现。迪普建议,情况应该相反。高端模块不应依赖于低端模块。两者都应该依赖于抽象。