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

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

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

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


当前回答

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

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

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

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

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

其他回答

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

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

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

在我看来,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.
   }
}

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

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

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

我同意依赖注入的好处,但我更喜欢自己构造和管理对象,使用与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-with-Ninject。您可以下载并使用Visual Studio运行它。这个例子使用了Ninject,但是所有的“new”语句都在一个位置,你可以通过改变使用哪个绑定模块来完全改变应用程序的运行方式。示例的设置使您可以绑定到服务的模拟版本或真实版本。在小型项目中,这可能无关紧要,但在大型项目中,这是一件大事。

先说清楚,我认为他们的优势是: 1)所有新语句位于代码根的一个位置。 2)只做一个改动就完全重构了代码。 3)“酷因素”加分,因为它……:酷。: p