当前位置: 首页 > 知识库问答 >
问题:

为什么要使用第三方DI容器而不是内置的ASP.NETCore DI容器?

丁阳羽
2023-03-14

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

共有3个答案

蒯卓君
2023-03-14

此外,有人能帮助我了解这些注册之间的区别吗?

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

https://stackoverflow.com/revisions/30681477/8

  • 瞬态-每次检索时都实例化
  • Scoped-每个超文本传输协议请求实例化一次,并将在超文本传输协议请求的生命周期内可用
  • Singleton-实例化一次,并将在您的应用程序的整个生命周期内可用
  • 实例-等效于单例,除了您提供对象实例而不是创建实例的框架

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

为了进一步解释为什么它被称为作用域,请考虑以下代码:

// app startup
var services = new ServiceCollection();
services.AddScoped<IService, Service>();
var startupServices = services.BuildServiceProvider();
// request init
var requestServices = statupServices.CreateScope().ServiceProvider;

因此,在 ASP.NET HttpContext.RequestServices 的创建方式与上面类似,其中 CreateScope 在请求开始时被调用。但它可以在 ASP.NET 之外的上下文中使用,在这种情况下,范围可能具有与每个请求不同的含义。

华欣怡
2023-03-14

这里解释一下:

  • 瞬态-每次创建一个新实例
  • 作用域-在当前作用域内创建单个实例。它相当于当前范围内的单例。
  • Singleton—创建一个实例,其行为与Singleton类似。
  • 实例-始终给定一个特定实例。您负责其初始创建

Alpha版本有此限制:

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

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

我的建议是从默认的开始,当(如果)你遇到一些你不能用它做的事情时,改变实现。

傅丁雷
2023-03-14

对于任何合理规模的应用程序的产品开发,实践松散耦合并遵循可靠的原则。NET Core的DI容器(MS.DI)不合适,因为:

  • 它无法帮助您验证配置,因此很难诊断由常见配置错误引起的问题。在规模合理的应用程序中,实际上很难自己发现这些错误。更新:MS 的版本 3。DI 现在包含一个名为 ValidateOnBuild 的功能,但它唯一要做的就是检查是否可以满足所有注册的所有依赖项。
  • 使用拦截器或装饰器以可维护的方式应用横切关注点是不可能的。这使得维护任何合理大小的应用程序更加昂贵。更新:有几个第三方库试图填补空白,但由于MS中的限制。DI,它们不能完全填补这一空白(例如,装饰开放通用注册,确保处理装饰实例等)。
  • 虽然女士。DI 支持将开放泛型抽象映射到开放泛型实现,其实现相当幼稚,并且无法使用具有类型约束、更复杂的泛型类型映射和方差的泛型类型。
  • 在使用Auto-Wireing时,不可能进行条件/上下文注册,例如,当有两个组件Service1Service2都依赖于ILogger时,您可能希望将Service1NullLogger注入,使用FileLogger注入Service2,或者您希望使用Logger注入Service1

存在这些限制的主要原因是因为内置容器的目标是为框架本身提供DI功能,同时保持其功能集最小化,希望更成熟的DI容器能够与之集成。换句话说,它试图充当最小公分母(LCD)。由于它的LCD功能,它永远也不能成长为一个成熟的DI容器,对应用程序开发来说是实用的(如果不违背作为LCD的promise的话)。

如果你从一个新的简单的项目开始,我的建议是应用纯DI。这意味着您可以在不使用容器和不创建自己的DI容器的情况下手工连接复合根中的组件。相反,您可以通过插入自定义IControllerActivator来解析您的类型。稍后,当自动连接、自动注册和拦截等特性可以提高组合根的可维护性时,切换到一个满足您需求的已建立的DI库。

 类似资料:
  • 因为我用的是匿名类,所以我不能用object方法,我认为这是对的,这个方法和引用对象没关系,但是我错了,以我有限的java经验,我不明白为什么,如果你能回答,提前谢谢!

  • 3.1.1 依赖和依赖注入 传统应用程序设计中所说的依赖一般指“类之间的关系”,那先让我们复习一下类之间的关系: 泛化:表示类与类之间的继承关系、接口与接口之间的继承关系; 实现:表示类对接口的实现; 依赖:当类与类之间有使用关系时就属于依赖关系,不同于关联关系,依赖不具有“拥有关系”,而是一种“相识关系”,只在某个特定地方(比如某个方法体内)才有关系。 关联:表示类与类或类与接口之间的依赖关系,

  • 问题内容: 在下面的示例中,我有一个具有以下样式的按钮… 但是它会自动缩放到100%,而不是内容的宽度。您可以设置一个明确的宽度,但是那样一来您的文本就不能自然地换行。 如何制作一个内部文本以flexbox居中但不能增长到适合容器大小的按钮? 问题答案: 而不是使用容器。 这会将容器从块级(占用其父级的整个宽度)切换到内联级(占用其内容的宽度)。 这上浆行为类似于对比。

  • docker 运行示例如下 网上找的相关示例,无外乎下面三种方式, 但我的测试却是全都不生效 以上方法,CentOS和Ubuntu都试过, 不额外在容器内安装工具, 不直接date -s 设置的情况下, 还有什么方法可以实现同步宿主机的时间吗?

  • 我有一个容器 ,其中 。它有一个子 。 怎样才能让孩子显得“内联”呢? 具体地说,我如何使孩子的宽度由它的内容决定,而不是扩展到父母的宽度? 我所尝试的: 我将子项设置为,但它仍然占用了整个宽度。我也尝试了所有其他显示属性,但都没有效果。 示例: null null http://codepen.io/donpinkus/pen/ygrxry 共2个答案 匿名用户 在容器上使用或在弹性项上使用。

  • 本文向大家介绍什么是用例内容?相关面试题,主要包含被问及什么是用例内容?时的应答技巧和注意事项,需要的朋友参考一下 主要分为三大部分:基本信息、用例主体、执行记录 基本信息:项目名称、功能模块名、用例设计人、测试执行人、功能特性、测试目的、预置条件、参考信息 用例主体:用例编号、测试对象、检查点、预置条件、用例说明、优先级、预期结果 执行记录:测试结果、缺陷编号、备注