依赖注入:手动与autofac

时间:2016-07-07 11:40:36

标签: c# dependency-injection autofac

Managing Dependency Injection in C# with Autofacdownloadable source code

的简洁方式解释

手动依赖注入

var di = new EmployeeObserver(employees, new Printer(Console.Out));
di.FindExperts();

使用autofac:

ContainerBuilder autofac = new ContainerBuilder();
autofac.Register(o => new EmployeeObserver(o.Resolve<IList<Employee>>(), o.Resolve<IPrinter>()));
autofac.RegisterType<Printer>().As<IPrinter>();
autofac.RegisterInstance(employees).As<IList<Employee>>();
autofac.RegisterInstance(Console.Out).As<TextWriter>();
using (var container = autofac.Build())
{
    container.Resolve<EmployeeObserver>().FindExperts();
}

在其他一些Q&amp; As中,它表示我们可以在编写单元测试时看到autofac的优势用法。

除此之外,有人可以提供理由或详细信息,为什么我应该使用更复杂的代码与autofac而不是手动依赖注入?

它说:

  

可能在这个特殊的例子中,很难理解为什么这种方法   比手动配置依赖注入更好,但是你   应该注意一件重要的事情 - 每个组件都是Autofac   独立于所有其他配置,这将是将要做的   当您的应用程序变得更加复杂时,会有很大的不同。

你能指出一个这个案例的复杂版本的例子,它显示了autofac使用与手工依赖的优势,我会坚持使用吗?

2 个答案:

答案 0 :(得分:1)

  

在其他一些Q&amp; As中,它说我们可以在编写单元测试时看到autofac的优势用途

你错过了这一点。 模仿依赖性,从而编写单元测试的能力是依赖注入作为模式本身的优势。

任何 DI容器(不仅仅是Autofac)的优点是能够以某种方式配置依赖关系并在复杂场景中使用此配置。

想象一下,你有一些课程,这取决于某些服务,而这又取决于其他一些服务,等等。

使用穷人的DI很难实现这一点,但DI容器可以解决这个问题。

答案 1 :(得分:1)

使用或不使用DI容器对单元测试没有影响。当您进行单元测试时,您不使用DI容器,因为单元测试通常会处理一个或多个可以轻松连接在一起的类。

请注意,是否使用DI容器来构建对象仍然是一个高度自以为是的问题。在这里,我根据我在项目中使用依赖注入的经验提供了一个透视图。

在我的一篇文章Why DI containers fail with “complex” object graphs中,我定义了这样一个简单对象图的概念:

  

具有以下两个属性的任何大小和深度的对象图:

     

a)对于任何接口(或抽象),在对象图中最多使用一个实现此类接口的类。

     

b)对于任何类,在对象图中最多使用一个实例(或具有完全相同的构造参数参数的多个实例)。这个单个实例可以在图中多次使用。

如果您有一个简单的对象图,请使用DI容器。

对于简单对象图的示例,请考虑您有20个服务接口,每个接口由单个类实现。例如。 IEmailService仅由EmailService实现,而ISMSService仅由SMSService等实现,并且您有30个ASP.NET控制器,每个控制器取决于任意数量的这些服务接口。一些服务还依赖于其他服务接口,例如, OrderService取决于IEmailService

当你没有一个简单的对象图时,即你有一个复杂的对象图(大多数应用SOLID principles的大型应用程序就是这种情况),不要使用DI容器而是使用Pure DI

如果您使用具有复杂对象图的DI容器,您将最终使用容器的复杂功能(如命名注册)来区分同一接口的不同实现或具有不同构造参数的对象之间。这将使您的composition root难以维护。

您可能需要查看我的this article,了解Pure DI如何使您的成分清洁。