【问题标题】:Dependency injection: by hand vs autofac依赖注入:手动 vs autofac
【发布时间】:2016-11-09 17:12:52
【问题描述】:

Managing Dependency Injection in C# with Autofacdownloadable source code非常简洁地解释

手动依赖注入

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

使用自动法:

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();
}

在其他一些问答中,它说我们可以在编写单元测试时看到 autofac 的优势使用。

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

上面写着:

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

你能否举一个这个案例的复杂版本的例子,它显示了我将坚持使用的 autofac 使用与手动依赖的优势?

【问题讨论】:

  • 你确定其他地方都在谈论在单元测试中使用autofac,还是在单元测试中只是依赖注入?您是专门询问单元测试部分,还是一般的 DI/autofac?这是一个相当广泛的主题,因此要在这里回答您需要非常准确地回答您的问题。
  • @JamesThorpe 尤其不是单元测试部分,而是后者
  • 来自马克·西曼:When to use a DI container.
  • @MatthewWatson 看起来不错的参考,但是可以将我的问题作为示例进行投影以便于消化

标签: c# dependency-injection autofac


【解决方案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 容器,而是使用@ 987654323@.

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

您可能想看看我的this article,了解 Pure DI 如何使您的组合根干净。

【讨论】:

    【解决方案2】:

    在其他一些问答中,它说我们可以在编写单元测试时看到 autofac 的优势使用

    你错过了重点。 模拟依赖的能力,因此,编写单元测试的能力是依赖注入作为模式本身的优势。

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

    想象一下,你有一些类,它依赖于一些服务,而这些服务又依赖于一些其他的服务,等等。

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

    【讨论】:

    • 我认为语言已经妨碍了。也许@asdf_enel_hak 在 DI 模式与容器方面走在了正确的轨道上,但表达得很糟糕。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 2017-11-07
    • 2012-09-23
    • 1970-01-01
    相关资源
    最近更新 更多