Dependency injection 是否有一个反模式将DI容器注入(几乎)每个类?

Dependency injection 是否有一个反模式将DI容器注入(几乎)每个类?,dependency-injection,Dependency Injection,最近我发现自己不太关心定义类的依赖项并将它们传递到构造函数中,但是我总是传递DI容器并将其保留在私有属性中。这样,我的类就不会有很好定义的依赖项,当我需要时,我可以从容器中获取所有内容 尽管我对这个解决方案有一些不好的感觉(除了访问容器造成的开销),但我实在想不出有多少缺点。也许松散的依赖项定义会降低类的可移植性,或者我在重构时会感到惊讶 你对此怎么看?完全错了。不要将DI容器放入对象中;他们不需要知道或关心他们正在被注射。这与“不要打电话给我们,我们会打电话给你”不符 反过来说:整个应用程序都

最近我发现自己不太关心定义类的依赖项并将它们传递到构造函数中,但是我总是传递DI容器并将其保留在私有属性中。这样,我的类就不会有很好定义的依赖项,当我需要时,我可以从容器中获取所有内容

尽管我对这个解决方案有一些不好的感觉(除了访问容器造成的开销),但我实在想不出有多少缺点。也许松散的依赖项定义会降低类的可移植性,或者我在重构时会感到惊讶


你对此怎么看?

完全错了。不要将DI容器放入对象中;他们不需要知道或关心他们正在被注射。这与“不要打电话给我们,我们会打电话给你”不符

反过来说:整个应用程序都知道DI引擎,但它从中获得了所需的bean


我想你可能会认为注释改变了一些关系,因为现在bean确实知道了一些关于它们连接在一起的事实。但当配置外部化为XML时,bean确实不知道DI

这是一种反模式,我敢打赌你还没有为你的代码编写测试,这真的很糟糕

当您开始编写测试时,您会发现您正在编写不可测试的代码,并且您:

  • 使用服务定位器反模式

  • 你违反了德米特的法律

  • 你没有遵循单一责任原则

  • 您正在隐藏对象的真实依赖项(不使用依赖项注入模式)

  • 在任何应用程序中,两大堆对象之间都没有真正的分离:

    • 业务对象:职责是业务逻辑、领域抽象
    • 布线和构建对象:职责是构建对象图
当你想为你的组件编写单元测试的那一天,你会后悔这个决定,你要么重构你的代码,要么编写集成测试,而不是简单的单元测试(创建一个测试容器并向这个容器注入模拟)

我的建议是阅读本指南来编写可测试代码:(这是在谷歌努力工作的人使用的指南)

如果您愿意,请从Misko Hevery提供的关于测试心理和干净代码讲座的视频开始:


我认为你在这里有点夸张了。我确实在为我的类编写单元测试,我不知道在我的DI容器中定义fixture而不是直接传递fixture如何使事情变得复杂。我也不同意你关于SRP的观点,只是部分同意你所说的德米特定律(它是一个容器)。您在这里暗示了太多的事情。将容器注入类只是服务定位器反模式的一种形式,并且(几乎)和调用静态服务定位器intance一样糟糕。另请参阅