.Net 核心 DI 范围验证,范围与瞬态?

Roy*_*mir 4 dependency-injection .net-core

阅读文档

当应用在开发环境中运行时,默认服务提供者会执行检查以验证:

  • 范围服务不是从根服务提供者直接或间接解析的。
  • 范围服务不会直接或间接注入单身人士

这意味着我不应该将 Scoped 服务注入到单例服务中。

基于瞬态服务在每次请求时都会创建一个实例的事实,VS 范围内的服务在整个请求的生命周期中都是单个实例:

题:

为什么 DI 仅验证范围服务而不验证瞬态服务?

cl0*_*0ud 5

从单例解析范围服务是危险的。可能会导致服务在处理后续请求时状态不正确。

从上面的 文档中描述了他们为什么要进行此检查。为了更好地理解这一点,我开始阅读关于各种生命周期的更多信息,我自己更像是一个 autofac 人,以了解注册的 .net 核心风格。

  • 范围注册需要一个服务生命周期,每个请求(连接)一个实例
  • Singleton 只有在注册时或构造函数运行时定义的单一状态。(在startup.cs)
  • 瞬态是每个构造函数注入的新实例,即每个依赖项。

通常,您会使用单例模式在您的应用程序生命周期等内存中维护某种状态,有很多用例,但重要的是要了解您的单例类的构造函数(在其中注入依赖项)将运行一次并且在您的整个应用程序生命周期内仅使用一次

您可以想象,在不考虑上述情况的情况下,将作用域或瞬态服务注入单例会导致一些……意想不到的结果,您期望您的服务遵守其特定的生命周期,但实际上它实际上只是同一个实例。每次都是由于单身人士的性质。

用我的理解来回答你的问题:注入到单例中的瞬态(虽然本质上不正确)仍然可以正常工作,因为它的生命周期很短并且破坏状态的风险很小,而作用域保证单个请求的生命周期(想想某种以请求缓存为例),在被注入到单例中时,scoped 无法兑现那个生命周期。

  • 怎么会?Singleton 的构造函数只运行一次。如果我注入一个临时服务,那么它永远不会被释放 (2认同)
  • 假设您有一个作用域服务,用于存储进入应用程序的 Web 请求的“GameId”(int) -“GameService.cs”,在应用程序中的某个时刻,“GameId”会发生变化,因为用户未成年且不允许玩该游戏并重定向到另一个新游戏 - 您同意“GameService”中的“GameId”属性更改吗?如果您将 GameService 注入到单例中,*gameid 将永远不会改变*。Microsoft 希望通过验证这一点来保护您免受这些错误的影响。瞬态服务不存储状态 - 因此您不会遇到问题。 (2认同)