为什么在内置的ASP.NET Core DI容器上使用第三方DI容器?

时间:2015-06-06 10:01:55

标签: asp.net dependency-injection asp.net-core

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

此外,有人可以帮我理解这些注册之间的区别吗?

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

4 个答案:

答案 0 :(得分:43)

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

  • 它无法帮助您验证配置,因此很难诊断常见错误配置引起的问题。在一个合理大小的应用程序中,实际上很难自己发现这些错误。
  • 无法以可维护的方式使用拦截器或cross-cutting concerns来应用decorators。这使得维护任何合理大小的应用程序非常昂贵。
  • 虽然它支持将开放式通用抽象映射到开放式通用实现,但它的实现相当幼稚,无法使用具有类型约束,更复杂的泛型类型映射和方差的泛型类型。
  • 无法进行条件/上下文注册,这样注册只会在使用自动连接时注入特定的一组消费者。例如当有两个组件Service1Service2都依赖于ILogger时,您可能希望将Service1NullLoggerService2一起注入FileLogger 1}},或者您希望Service1注入Logger<Service1>Service2注入Logger<Service2>

如果您从一个新的简单项目开始,我的建议是应用Pure DI(这意味着Composition Root 中的手工连线组件,而不使用使用容器)通过插入your custom IControllerActivator来解决您的类型问题。稍后,当批量注册和装饰等功能可以提高组合根的可维护性时,请切换到符合您要求的已建立的DI库之一。

答案 1 :(得分:17)

在此解释:

  • 瞬态 - 每次都会创建一个新实例
  • Scoped - 在当前范围内创建单个实例。它相当于当前范围内的Singleton
  • Singleton - 创建单个实例,它就像一个单例
  • 实例 - 始终提供特定实例。您负责其初始创建

Alpha版本有这个限制:

  • 它只支持构造函数注入
  • 它只能解析具有一个且只有一个公共构造函数的类型
  • 它不支持高级功能(如每个线程范围或自动发现)

如果您没有编写非常复杂的产品默认DI容器应该足够您。在其他情况下,您可以尝试已经提到的具有高级功能的库。

我的建议是从默认开始并更改实现 什么时候(如果)你碰到了一些你无法做到的事情。

答案 2 :(得分:6)

  

这些注册之间有什么区别?

  • 瞬态 - 每次检索时实例化
  • Scoped - 每个http请求实例化一次,并且可以在http请求的生命周期内使用
  • 单例 - 实例化一次,将在应用程序的整个生命周期内可用
  • 实例 - 除了提供对象实例而不是创建实例的框架
  • 之外,等同于单例

来源:http://www.khalidabuhakmeh.com/asp-vnext-dependency-injection-lifecycleshttp://dotnetliberty.com/index.php/2015/10/15/asp-net-5-mvc6-dependency-injection-in-6-steps/

答案 3 :(得分:5)

回答您的第一个问题:似乎ASP.NET docs已更新,现在明确说明每种注册类型:

  

可以使用以下生命周期配置ASP.NET服务:

     

<强>瞬态

     

每次请求时都会创建瞬态生命周期服务。   这种生命周期最适合轻量级,无状态服务。

     

<强>作用域

     

每个请求都会创建一次范围生命周期服务。

     

<强>的Singleton

     

Singleton生命周期服务是在第一次创建时创建的   请求,然后每个后续请求将使用相同的   实例。如果您的应用程序需要单例行为,则允许   建议使用服务容器来管理服务的生命周期   而不是实现单身设计模式和管理你的   对象在课堂上的生命。

     

实例 [仅限RTM!]

     

您可以选择直接向服务容器添加实例。   如果这样做,此实例将用于所有后续请求   (这种技术将创建一个单例范围的实例)。一把钥匙   Instance服务和Singleton服务之间的区别就在于此   Instance服务是在ConfigureServices中创建的   Singleton服务在第一次请求时是延迟加载的。

在RTM中更新

请注意,Asp.Net Core RTM docs实例已删除。实例与Singleton基本相同,但它们具有不同的初始化语义(Singleton是延迟加载的)。但是现在没有AddInstance API,只有AddSignleton可以接受已经创建的实例。