我已经使用依赖注入(DI)有一段时间了,在构造函数、属性或方法中进行注入。我从未觉得有必要使用反转控制(IoC)容器。然而,我读得越多,我就越感到来自社区的使用IoC容器的压力。

我使用过StructureMap、NInject、Unity和Funq等。net容器。我仍然没有看到IoC容器将如何受益/改进我的代码。

我也害怕在工作中开始使用容器,因为我的许多同事会看到他们不理解的代码。他们中的许多人可能不愿意学习新技术。

请说服我,我需要使用IoC容器。当我在工作中与其他开发人员交谈时,我将使用这些论点。


当前回答

As you continue to decouple your classes and invert your dependencies, the classes continue to stay small and the "dependency graph" continues to grow in size. (This isn't bad.) Using basic features of an IoC container makes wiring up all these objects trivial, but doing it manually can get very burdensome. For example, what if I want to create a new instance of "Foo" but it needs a "Bar". And a "Bar" needs an "A", "B", and "C". And each of those need 3 other things, etc etc. (yes, I can't come up with good fake names :) ).

使用IoC容器为您构建对象图可以大大降低复杂性,并将其推到一次性配置中。我只需说“给我创建一个Foo”,它就会计算出构建一个Foo需要什么。

有些人将IoC容器用于更多的基础设施,这对于高级场景来说是很好的,但在这些情况下,我同意它会使新开发人员难以阅读和调试代码。

其他回答

不需要IoC容器。

但是如果您严格遵循依赖注入模式,您会发现使用一个依赖注入模式将会删除大量冗余的、无聊的代码。

无论如何,这通常是使用一个库/框架的最佳时机——当你了解它在做什么并且不需要库也能完成它的时候。

就我个人而言,我使用IoC作为我的应用程序的某种结构图(是的,我也喜欢StructureMap;))。这使得在测试期间用Moq实现代替我通常的接口实现变得很容易。创建一个测试设置可以像对我的ioc -框架进行一个新的初始化调用一样简单,用一个mock代替任何一个测试边界类。

这可能不是IoC存在的目的,但这是我发现自己使用它最多的地方。

我知道这是一个相当老的帖子,但它似乎仍然相当活跃,我想我可以贡献一些在其他回答中没有提到的观点。

我同意依赖注入的好处,但我更喜欢自己构造和管理对象,使用与Maxm007在回答中概述的模式相似的模式。我发现了使用第三方容器的两个主要问题:

1) Having a 3rd party library manage the lifetime of your objects "automagically" can lend itself to unexpected results. We have found that especially in large projects, you can have vastly more copies of an object than you expect, and more than you would if you were manually managing the lifecycles. I'm sure this varies depending on the framework used, but the problem exists nonetheless. This can also be problematic if your object holds resources, data connections, etc., since the object can sometimes live longer than you expect. So inevitably, IoC containers tend to increase the resource utilization and memory footprint of an application.

2) IoC containers, in my opinion, are a form of "black box programming". I have found that in particular, our less experienced developers tend to abuse them. It allows the programmer to not have to think about how objects should relate to each other or how to decouple them, because it provides them with a mechanism in which they can simply grab any object they want out of thin air. Eg, there may be a good design reason that ObjectA should never know about ObjectB directly, but rather than creating a factory or bridge or service locator, an inexperienced programmer will simply say "no problem, I'll just grab ObjectB from the IoC container". This can actually lead to increased object coupling, which is what IoC is supposed to help prevent.

关于Unity也是如此。如果房子太大,你会听到房梁的吱吱声。

当人们开始大谈IoC代码看起来有多干净时,我从不感到惊讶,这些人在90年代曾说过c++中的模板是如何优雅的方式,但现在却会谴责它们是神秘的。呸!

我认为IoC的大部分价值都是通过使用DI获得的。既然你已经这样做了,剩下的好处是递增的。

你得到的值将取决于你正在处理的应用程序的类型:

For multi-tenant, the IoC container can take care of some of the infrastructure code for loading different client resources. When you need a component that is client specific, use a custom selector to do handle the logic and don't worry about it from your client code. You can certainly build this yourself but here's an example of how an IoC can help. With many points of extensibility, the IoC can be used to load components from configuration. This is a common thing to build but tools are provided by the container. If you want to use AOP for some cross-cutting concerns, the IoC provides hooks to intercept method invocations. This is less commonly done ad-hoc on projects but the IoC makes it easier.

我以前写过这样的功能,但如果我现在需要这些功能中的任何一个,我宁愿使用一个预先构建并经过测试的工具,如果它适合我的架构的话。

正如其他人所提到的,您还可以集中配置希望使用的类。虽然这可能是一件好事,但代价是误导和复杂化。大多数应用程序的核心组件都没有被替换,因此很难做出取舍。

我使用IoC容器,并欣赏其功能,但不得不承认我注意到了权衡:我的代码在类级别变得更加清晰,而在应用程序级别变得不那么清晰(即可视化控制流)。