依赖注入最佳实践

8

我在我的代码中使用依赖注入(使用Ninject),认为自己做得很好,直到遇到了一个性能问题,这是由于对DI容器的理解错误造成的。似乎有很多关于如何使用DI框架的信息,但是关于不应该使用它们或如何最好地使用它们的信息并不多(至少我没有找到)。

我想写出我认为的一些最佳实践,并看看其他人是否同意我,以及其他人可以提出哪些最佳实践。

  • 每个应用程序或AppDomain使用一个内核
  • 仅将DI容器用于长期存在的Singleton对象,对于短暂的瞬态对象,请使用工厂(或其他方法)
  • 优先使用构造函数注入而不是属性或字段注入
  • 请求对象,不要构建它们
  • 其他??指向好的博客文章/文章的指针??

什么是内核?这是Ninject特定的概念吗(我在其他地方没有看到过)? - Andriy Volkov
此外,setter和构造函数注入的选择是一个宗教性的争论,因此应该避免。 - Andriy Volkov
2个回答

7
这是一份重要的清单(其中一些也出现在原始帖子中):
  • 代码应该不知道使用了哪个 DI 容器(如果有的话)
  • 将整个应用程序组成在应用程序的根目录中(组合根)
  • 偏好构造函数注入
我不能说我同意您关于 Singleton vs. Transient 对象的观点。DI 的整个意义在于外部机制(例如 DI 容器)决定了任何给定依赖项的生存期,而不是其他人,因此您需要让所有依赖项都由 DI 容器管理。

嗨Mark,看这里的讨论(http://groups.google.com/group/ninject/browse_thread/thread/41ec03527da9f0f8)关于Ninject在应用程序中的性能。像你一样,我认为DI容器应该随处可用,但DI容器的开销如此之大,以至于创建大量短暂对象可能会产生干扰。你的建议也许对Web应用程序很好,但在其他领域就不是那么合适了。 - Jeffrey Cameron
我浏览了一下那个讨论,但我认为我同意Nate的观点。依赖注入应该用于解决和注入依赖项,但如果通过DI容器创建数十万个对象,那么整体设计肯定有问题。这从来不是DI的初衷。我可以在我的清单中添加另一个要点:“优先考虑解耦易变依赖项而非稳定依赖项”,但这更多是一般的设计建议,而不是特定的DI事项。 - Mark Seemann
2
我同意关于瞬态对象的观点 - 大多数使用依赖注入的应用程序都会创建大量的瞬态对象。一些容器(如Unity和即将发布的Autofac 2)默认为瞬态而非单例。我认为“偏爱单例”不能被视为最佳实践 - 它似乎更像是对特定场景下某个容器性能的评价。 - Nicholas Blumhardt

4

仅将DI容器用于长期存在的单例对象,对于短期生存的临时对象,请使用工厂(或其他方法)

但是确保使用DI将工厂注入到需要它们的位置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接