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

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

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

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


当前回答

Ioc容器解决了一个你可能没有的问题,但这是一个很好的问题

http://kozmic.net/2012/10/23/ioc-container-solves-a-problem-you-might-not-have-but-its-a-nice-problem-to-have/

其他回答

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

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

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

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

就我个人而言,我使用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.

在我看来,IoC的最大好处是能够集中配置依赖项。

如果你正在使用依赖注入,你的代码可能是这样的

public class CustomerPresenter
{
  public CustomerPresenter() : this(new CustomerView(), new CustomerService())
  {}

  public CustomerPresenter(ICustomerView view, ICustomerService service)
  {
    // init view/service fields
  }
  // readonly view/service fields
}

如果你使用静态IoC类,而不是(恕我直言)更混乱的配置文件,你可以有这样的东西:

public class CustomerPresenter
{
  public CustomerPresenter() : this(IoC.Resolve<ICustomerView>(), IoC.Resolve<ICustomerService>())
  {}

  public CustomerPresenter(ICustomerView view, ICustomerService service)
  {
    // init view/service fields
  }
  // readonly view/service fields
}

然后,你的静态IoC类看起来像这样,我在这里使用Unity。

public static IoC
{
   private static readonly IUnityContainer _container;
   static IoC()
   {
     InitializeIoC();
   }

   static void InitializeIoC()
   {
      _container = new UnityContainer();
      _container.RegisterType<ICustomerView, CustomerView>();
      _container.RegisterType<ICustomerService, CustomerService>();
      // all other RegisterTypes and RegisterInstances can go here in one file.
      // one place to change dependencies is good.
   }
}

在。net世界里AOP还不是很流行,所以对于依赖注入来说,一个框架是你唯一真正的选择,不管你是自己写一个框架还是使用另一个框架。

如果您使用AOP,则可以在编译应用程序时进行注入,这在Java中更为常见。

DI有很多好处,比如减少耦合,从而使单元测试更容易,但是您将如何实现它呢?你想用反射来自己做吗?