Managing Dependency Injection in C# with Autofac用 downloadable 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/