c# - 依赖注入(inject) : by hand vs autofac

标签 c# dependency-injection autofac

Managing Dependency Injection in C# with Autofacdownloadable source code 以非常简洁的方式解释

手动依赖注入(inject)

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&A中,它说我们可以在编写单元测试时看到autofac的优势用法。

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

它说:

May be on this particular example it's hard to see why this approach is better than configuring dependency injection by hand, but you should notice one important thing - with Autofac each component is configured independently of all the others, and this is what will make a big difference when your application become more complex.

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

最佳答案

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

请注意,是否使用 DI 容器来组合您的对象仍然是一个高度自以为是的问题。在这里,我根据我在项目中使用依赖注入(inject)的经验提供了一个观点。

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

An object graph of any size and any depth that has the following two attributes:

a) For any interface (or abstraction) at most one class that implements such interface is used in the object graph.

b) For any class, at most one instance is used in the object graph (or multiple instances with the exact same construction parameter arguments). This single instance can be used multiple times in the graph.

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

举一个简单对象图的例子,假设您有 20 个服务接口(interface),每个接口(interface)都由一个类实现。例如。 IEmailService仅由EmailService实现,ISMSService仅由SMSService实现,等等,你有30 个 ASP.NET Controller ,每个都依赖于任意数量的这些服务接口(interface)。此外,一些服务依赖于其他服务接口(interface),例如OrderService 依赖于 IEmailService

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

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

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

关于c# - 依赖注入(inject) : by hand vs autofac,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38244542/

相关文章:

c# - dotnet core autofac 和 json 配置它们可以在控制台应用程序中一起工作吗

c# - 基于ctor参数构建Autofac组件

c# - 为什么xna中的draw()需要tint参数

c# - 将控制台应用程序屏幕保存在 .txt 文件中

android - 应用恢复后单例对象变为空

c# - 如何解析 Autofac 中的依赖项列表?

c# - 为参数的具体名称注册字符串值

c# - 如何删除列表框中的多个选定项?

c# - Linq 中的空引用异常

php - 为什么服务定位器是以下示例中的反模式?