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

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

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

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


当前回答

我是声明式编程的爱好者(看看我回答了多少SQL问题),但我所研究的IoC容器似乎太神秘了。

...或者IoC容器的开发人员无法编写清晰的文档。

...或者两者在某种程度上都是正确的。

我不认为IoC容器的概念不好。但是实现必须足够强大(即灵活),以便在各种各样的应用程序中都有用,同时又要简单易懂。

可能是其他的六个中的六个。真正的应用程序(不是玩具或演示)必然是复杂的,会有许多极端情况和规则的例外。您可以将这种复杂性封装在命令式代码中,也可以封装在声明式代码中。但你必须在某个地方表示它。

其他回答

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

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

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

无论何时使用“new”关键字,您都是在创建一个具体的类依赖,您的头脑中应该敲响警钟。孤立地测试这个物体变得更加困难。解决方案是对接口进行编程并注入依赖项,这样对象就可以用实现该接口的任何东西进行单元测试。模拟)。

The trouble is you have to construct objects somewhere. A Factory pattern is one way to shift the coupling out of your POXOs (Plain Old "insert your OO language here" Objects). If you and your co-workers are all writing code like this then an IoC container is the next "Incremental Improvement" you can make to your codebase. It'll shift all that nasty Factory boilerplate code out of your clean objects and business logic. They'll get it and love it. Heck, give a company talk on why you love it and get everyone enthused.

如果你的同事还没有做DI,那么我建议你先专注于DI。宣传如何编写易于测试的干净代码。干净的DI代码是比较困难的部分,一旦做到了这一点,将对象连接逻辑从Factory类转移到IoC容器应该是相对简单的。

对我来说,使用IoC容器的最大好处(我个人使用Ninject)是消除了设置和其他类型的全局状态对象的传递。

我不为web编程,我的是一个控制台应用程序,在对象树的许多地方,我需要访问用户指定的设置或元数据,这些设置或元数据是在对象树的一个完全独立的分支上创建的。通过IoC,我简单地告诉Ninject将设置作为一个单例(因为它们总是只有一个实例),在构造函数中请求设置或字典,然后立即…它们在我需要的时候神奇地出现了!

如果不使用IoC容器,我将不得不通过2,3,…传递设置和/或元数据。在它被需要它的对象实际使用之前,有n个对象。

DI/IoC容器还有许多其他好处,正如其他人在这里详细介绍的那样,从创建对象到请求对象的想法可能会令人难以置信,但使用DI对我和我的团队非常有帮助,所以也许您可以将其添加到您的库中!

想必没有人强迫您使用依赖注入容器框架。您已经使用DI来解耦类并改进可测试性,因此您将获得许多好处。简而言之,你喜欢简单,这通常是件好事。

如果您的系统达到了一个复杂的水平,手动DI变成了一件苦差事(也就是说,增加了维护),请将其与DI容器框架的团队学习曲线进行权衡。

如果您需要对依赖生命周期管理进行更多的控制(也就是说,如果您觉得需要实现单例模式),请查看DI容器。

如果使用DI容器,请只使用需要的特性。跳过XML配置文件,在代码中配置即可。坚持构造函数注入。Unity或StructureMap的基本内容可以压缩到几个页面中。

Mark Seemann写了一篇很棒的博文:什么时候使用DI容器