依赖注入最佳实践和反模式

Posted

技术标签:

【中文标题】依赖注入最佳实践和反模式【英文标题】:Dependency Injection best practices and anti-patterns 【发布时间】:2010-12-13 13:03:38 【问题描述】:

我在依赖注入方面相对不熟练,我想学习一些在使用 DI 时分别使用和避免的最佳实践和反模式。

【问题讨论】:

我不认为“语言无关”在这里有帮助:不同的语言决定了完全不同的方法 - 你真的不想在 C++ 中做同样的事情,比如 Ruby。 那么是否值得针对每种语言提出单独的问题?不过,我想有足够的通用模式,所以一个通用的问题是有序的。 我鼓励任何有兴趣为这个问题做出贡献的人转而查看 dependency injection docs 主题。 【参考方案1】:

我真的很喜欢这篇关于 DI 的文章,因为它面向那些没有大量 DI 经验或者甚至不知道它是什么的人。

https://mtaulty.com/2009/08/10/m_11554/

什么是 Unity?

It’s a “dependency injection container”.

现在,那时有一群人 读到这里会说“是的,我们知道 我们已经在使用它了 A、B、C 或者我们选择不使用它 出于 X,Y,Z 的原因”,我想象一个 其他人可能会说;

“Huh? What’s a dependency injection container?”

这篇文章是给后者的—— 这并不意味着详尽,但 希望它不完全 也无济于事:-)

【讨论】:

【参考方案2】:

在我看来,Dhanji Prasanna 的书Dependency Injection 是软件设计师的必读之书,无论是初学者还是专家。它直接处理您的 DI 问题。

【讨论】:

另一本好书是Dependency Injection in .NET from Mark Seemann。【参考方案3】:

Guice 的user's guide 中有一个最佳实践部分。

【讨论】:

【参考方案4】:

我发现,当我看到违反 Law of Demeter 的情况时,这暗示我可能需要依赖注入。

例如:

void doit()

    i += object.anotherobject.addvalue; //violation of Law of Demeter

有时暗示我可能想要依赖注入 anotherobject

【讨论】:

这有点道理,虽然有点飞跃,而且不完整。如果你发现违反了得墨忒耳定律,你就会找到一个选择抽象的机会。任何时候你抽象,你都有机会选择注入依赖而不是自己创建它。所以这是一个指标,但只是一个指标。可能有比这更多的抽象机会,并且在实施成本高于您可能摆脱它的地方避免 DI 可能是有用的。不过,+1。【参考方案5】:

我关于何时使用 DI 的基本规则是我将在层之间注入,因此我的控制器和 dao 之间将是一个层,所以我可以注入,这样如果我想模拟一个层,我可以。

我认为在同一层中使用 DI 不是一个好主意,主要是因为该层应该紧密耦合,因为它们是相关的,除非您有一个有用的用户故事。

例如,如果您的 DAO 可能位于不同的计算机上,那么您可能需要能够假装它们是一层,但使用 DI 在一台机器上和不同的机器之间实际切换。然后开发人员可以在一台机器上做所有事情,它应该在不同的机器上工作。

但是,除非有迫切的需要,否则我认为同一层内的 DI 是不必要的复杂化。

【讨论】:

在层内使用依赖注入,您将重用现有组件实例,从而节省资源。另外我想说的是,您通过强制模块化设计来培养良好的编程习惯。 我只是看到它变得比它需要的更复杂,但这取决于层上的内容。我倾向于只在层之间进行,但这就是为什么我解释了为什么在层之间进行这样做会有所帮助,而不是我会建议的事情。【参考方案6】:

这是一个依赖注入反模式:Multiple Constructors。

【讨论】:

以上是关于依赖注入最佳实践和反模式的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core 依赖注入最佳实践——提示与技巧

使用具有依赖注入的策略和工厂模式

Ninject之旅之七:Ninject依赖注入

Blazor University (44)依赖注入

如何将依赖项注入实现接口的类中?

领域驱动设计中依赖注入的最佳位置