我已经使用依赖注入(DI)有一段时间了,在构造函数、属性或方法中进行注入。我从未觉得有必要使用反转控制(IoC)容器。然而,我读得越多,我就越感到来自社区的使用IoC容器的压力。
我使用过StructureMap、NInject、Unity和Funq等。net容器。我仍然没有看到IoC容器将如何受益/改进我的代码。
我也害怕在工作中开始使用容器,因为我的许多同事会看到他们不理解的代码。他们中的许多人可能不愿意学习新技术。
请说服我,我需要使用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.
}
想必没有人强迫您使用依赖注入容器框架。您已经使用DI来解耦类并改进可测试性,因此您将获得许多好处。简而言之,你喜欢简单,这通常是件好事。
如果您的系统达到了一个复杂的水平,手动DI变成了一件苦差事(也就是说,增加了维护),请将其与DI容器框架的团队学习曲线进行权衡。
如果您需要对依赖生命周期管理进行更多的控制(也就是说,如果您觉得需要实现单例模式),请查看DI容器。
如果使用DI容器,请只使用需要的特性。跳过XML配置文件,在代码中配置即可。坚持构造函数注入。Unity或StructureMap的基本内容可以压缩到几个页面中。
Mark Seemann写了一篇很棒的博文:什么时候使用DI容器