为什么要在内置的 ASP.NET Core DI 容器上使用第三方 DI 容器? [英] Why would one use a third-party DI Container over the built-in ASP.NET Core DI Container?

查看:22
本文介绍了为什么要在内置的 ASP.NET Core DI 容器上使用第三方 DI 容器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于目前缺乏关于 DI 主题的文档 - 依赖注入.与现有解决方案(Ninject、Autofac、StructureMap)相比,使用内置 DI 的优缺点是什么?默认依赖注入(如果有)的当前限制是什么?

As currently there is lack of documentation on DI topic - Dependency Injection. What are pros/cons of using built-in DI over existing solutions like (Ninject, Autofac, StructureMap)? And what are current limitations of default dependency injection (if any)?

另外,谁能帮我了解一下这些注册有什么区别?

Additionally, can someone help me to understand what is the difference between these registrations?

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<IService, Service>();
    services.AddScoped<IService, Service>();
    services.AddSingleton<IService, Service>();
    services.AddInstance(service);
}

推荐答案

对于任何实践松耦合并遵循 SOLID 原则的合理大小的应用程序的产品开发,.NET Core 的 DI 容器是不适合的,因为:

For product development of any reasonably sized application that practice loose coupling and follows the SOLID principles, .NET Core's DI container is unsuited, because:

  • 它无法帮助您验证配置,因此很难诊断出常见的错误配置引起的问题.在一个合理大小的应用程序中,实际上很难自己发现这些错误.更新:MS.DI 的第 3 版现在包含一个名为 ValidateOnBuild 的功能,但它唯一能做的就是检查是否可以创建所有注册.
  • 不可能使用拦截器或 Cross-Cutting Concerns="https://en.wikipedia.org/wiki/Decorator_pattern" rel="nofollow noreferrer">装饰器 以可维护的方式.这使得维护任何合理大小的应用程序非常昂贵.更新:有几个第三方库试图填补这个空白,但由于 MS.DI 的限制,它们不能完全填补这个空白(例如装饰开放通用注册,确保处理装饰实例等)
  • 虽然它支持将开放泛型抽象映射到开放泛型实现,但它的实现相当幼稚并且无法使用具有类型约束、更复杂的泛型类型映射和差异的泛型类型.
  • 不可能进行条件/上下文注册,这样注册只会被注入到特定的一组消费者,同时使用自动接线.例如当有两个组件 Service1Service2 都依赖于 ILogger 时,你可能想用 注入 Service1>NullLoggerService2FileLogger,或者你希望 Service1 被注入 Logger> 和 Service2Logger.
  • It doesn't help you in verifying your configuration, making it really hard to diagnose problems that come from common misconfigurations. In a reasonably sized application, it's actually quite hard to spot these mistakes yourself. UPDATE: Version 3 of MS.DI now contains a feature called ValidateOnBuild, but the only thing it does is check whether all registrations can be created.
  • It is impossible to apply Cross-Cutting Concerns using interceptors or decorators in a maintainable fashion. This makes maintaining any reasonably sized application really expensive. UPDATE: There are several third-party libraries that try to fill the gap, but due to limitations in MS.DI, they can't completely fill this gap (e.g. decorate open-generic registrations, ensure disposal of decorated instances, etc.)
  • Although it supports mapping of open-generic abstractions to open-generic implementations, its implementation is rather naive and is unable to work with generic types with type constraints, more complex generic type mappings, and variance.
  • It is impossible to make conditional/contextual registrations, in such way that registrations only get injected to a certain set of consumers, while using Auto-Wiring. e.g. when having two components Service1 and Service2 that both depend on ILogger, you might want to inject Service1 with NullLogger and Service2 with FileLogger, or you want Service1 to be injected with Logger<Service1> and Service2 with Logger<Service2>.

存在这些限制的主要原因是,内置容器的目标是为框架本身提供 DI 功能,同时将其功能集保持在最低限度,希望能有更成熟的 DI 容器能够与它集成.换句话说,它尝试充当最小公分母 (LCD).由于其 LCD 功能,它永远无法成长为适用于应用程序开发的完整 DI 容器(这不会违背作为 LCD 的承诺).

The main reason for those limitations to exist is because it's the goal of the built-in container to provide DI capabilities to especially the framework itself, while keeping its feature set to a minimum in the hope that more mature DI containers would be able to integrate with it. In other words, it tries to act as an Least-Common Denominator (LCD). Because of its LCD function, it can never grow to a full-fletched DI Container that is practical for application development (not without breaking the promise of being an LCD).

如果你从一个新的简单项目开始,我的建议是申请 纯DI.这意味着您在 组合根 使用容器和<强>无需创建您的自己 DI 容器.相反,您通过插入 您的自定义 IControllerActivator.稍后,当自动连接、自动注册和拦截等功能可以提高您的组合根的可维护性时,请切换到符合您要求的已建立的 DI 库之一.

If you start with a new and simple project, my advice is to apply Pure DI. This means you hand-wire components inside the Composition Root without using a container and without creating your own DI Container. Instead you resolve your types by plugging in your custom IControllerActivator. Later on, when features such as Auto-Wiring, Auto-Registration and Interception would improve maintainability of your Composition Root, switch to one of the established DI libraries that fits your requirements.

这篇关于为什么要在内置的 ASP.NET Core DI 容器上使用第三方 DI 容器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆