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

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

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

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


当前回答

原因如下。这个项目被称为IOC-with-Ninject。您可以下载并使用Visual Studio运行它。这个例子使用了Ninject,但是所有的“new”语句都在一个位置,你可以通过改变使用哪个绑定模块来完全改变应用程序的运行方式。示例的设置使您可以绑定到服务的模拟版本或真实版本。在小型项目中,这可能无关紧要,但在大型项目中,这是一件大事。

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

其他回答

使用容器主要是将命令式/脚本化的初始化和配置风格改为声明式的。这可能会有一些不同的有益影响:

减少主程序启动的繁琐程序。 支持相当深入的部署时重新配置功能。 使依赖注入样式成为新工作阻力最小的路径。

当然,可能会有困难:

需要复杂启动/关闭/生命周期管理的代码可能不容易适应容器。 你可能需要处理个人、流程和团队文化方面的问题——但这就是你为什么要问…… 一些工具包本身正在迅速成为重量级的工具,鼓励了许多依赖注入容器开始反对的那种深度依赖。

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

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

IoC容器也适用于装入嵌套很深的类依赖项。例如,如果你有以下代码使用依赖注入。

public void GetPresenter()
{
    var presenter = new CustomerPresenter(new CustomerService(new CustomerRepository(new DB())));
}

class CustomerPresenter
{
    private readonly ICustomerService service;
    public CustomerPresenter(ICustomerService service)
    {
        this.service = service;
    }
}

class CustomerService
{
    private readonly IRespository<Customer> repository;
    public CustomerService(IRespository<Customer> repository)
    {
        this.repository = repository;
    }
}

class CustomerRepository : IRespository<Customer>
{
    private readonly DB db;
    public CustomerRepository(DB db)
    {
        this.db = db;
    }
}

class DB { }

如果你把所有这些依赖都加载到一个IoC容器中,你可以解析CustomerService,所有的子依赖都会自动得到解析。

例如:

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

   static void InitializeIoC()
   {
      _container = new UnityContainer();
      _container.RegisterType<ICustomerService, CustomerService>();
      _container.RegisterType<IRepository<Customer>, CustomerRepository>();
   }

   static T Resolve<T>()
   {
      return _container.Resolve<T>();
   }
}

public void GetPresenter()
{
   var presenter = IoC.Resolve<CustomerPresenter>();
   // presenter is loaded and all of its nested child dependencies 
   // are automatically injected
   // -
   // Also, note that only the Interfaces need to be registered
   // the concrete types like DB and CustomerPresenter will automatically 
   // resolve.
}

依赖注入在ASP。NET项目可以用几行代码完成。我认为,当你的应用程序使用多个前端并需要单元测试时,使用容器会有一些好处。

在我看来,您已经构建了自己的IoC容器(使用Martin Fowler描述的各种模式),并且正在询问为什么其他人的实现比您的更好。

所以,你有一堆已经工作的代码。并且想知道为什么要用其他人的实现来替换它。

考虑第三方IoC容器的优点

你可以免费修理bug 图书馆的设计可能比你的好 人们可能已经熟悉了特定的库 图书馆可能比你的快 它可能有一些您希望实现但没有时间实现的特性(您有服务定位器吗?)

Cons

你可以免费引入bug:) 图书馆的设计可能比你的还差 你必须学习一个新的API 太多你永远不会用到的功能 调试不是你写的代码通常比较困难 从以前的IoC容器迁移可能很乏味

所以,权衡利弊,做出决定吧。