asp.net core 2.1中的SharedResource本地化和简单注入器

asp.net core 2.1中的SharedResource本地化和简单注入器,.net,asp.net-core,localization,ioc-container,simple-injector,.net,Asp.net Core,Localization,Ioc Container,Simple Injector,我在ASP.NET core 2.1中有一个ASP.NET web api,并且我已经实现了一个共享资源,如前所述。这个很好用 该行: services.AddLocalization() 将本地化添加到内置的IOC容器中。(我认为这至少是魔法发生的地方) 现在我已经为我自己的类在混合中添加了简单的注入器,我有一个注册为异步作用域的类,该类被注入共享资源(通过IStringLocalizer)。但是,IStringLocalizer的作用域为瞬态,这与异步作用域不兼容(因为它的作用域更长)。显

我在ASP.NET core 2.1中有一个ASP.NET web api,并且我已经实现了一个共享资源,如前所述。这个很好用

该行:

services.AddLocalization()
将本地化添加到内置的IOC容器中。(我认为这至少是魔法发生的地方)


现在我已经为我自己的类在混合中添加了简单的注入器,我有一个注册为异步作用域的类,该类被注入共享资源(通过IStringLocalizer)。但是,IStringLocalizer的作用域为瞬态,这与异步作用域不兼容(因为它的作用域更长)。显然,我可以通过将选项“SuppressLifestyleMismatchVerification”设置为true来解决这个问题,但这听起来不对。(在这种情况下,这可能无关紧要,但通过使用此选项,我可以掩盖我可能遇到的任何其他问题)是否有解决此问题的方法?例如,我可以更改共享资源的范围吗?

您看到的是两个宇宙碰撞;两个DI库都有自己的、不兼容的瞬态定义:

  • 简单喷油器认为具有瞬态生活方式的部件寿命短或短暂。这就是为什么简单的注入器不允许瞬变注入范围内的元件;一个范围可能比被认为是短暂的要长得多
  • ASP.NET核心不考虑瞬态组件是短暂的。相反,在.NET内核中,
    瞬态
    组件的预期寿命与其使用者的预期寿命一样长。甚至声明“此生命周期最适合轻量级、无状态服务。”
更新对于Simple Injector v5,此行为已稍微放宽,现在(默认情况下)可以将瞬态注入范围内的组件。然而,瞬变含义的定义保持不变,这意味着当您尝试将瞬变注入单态时,Simple Injector仍然认为这是一个错误

正是由于这种行为,Microsoft.Extensions.DependencyInjection(MS.DI)容器允许向单例和作用域使用者注入瞬态

我甚至认为微软对他们的生活方式的命名是错误的,因为实际的行为是每个消费者都有一个依赖实例。微软似乎从Autofac复制了这种行为。然而,Autofac确实为这种生活方式命名了
InstancePerDependency
,如果你问我的话,这是一个更明显的名字

但奇怪的是,微软的
AddLocalization
扩展方法
StringLocalizer
是暂时的。这很奇怪,因为除了包装的
IStringLocalizer
StringLocalizer
没有任何状态。不仅如此,它包装的
IStringLocalizer
是由注入的
IStringLocalizerFactory
生成的,并且可以预期是同一个实例(这是由
ResourceManagerStringLocalizerFactory
返回实例的事实强制实现的)

如上所述,在MS.DI中,
Transient
意味着“我会活得和我的消费者一样长。”这实际上意味着
StringLocalizer
实例可以活得和单例一样长,这意味着:在整个应用程序期间

从这一点上讲,本地化团队选择了一种过渡的生活方式,甚至在MS.DI中,这实际上是非常奇怪的。过渡只意味着创建了更多的实例,而调用IStringLocalizerFactory的频率比需要的要高。我发现单例生活方式更明显注册

长话短说,我建议使用singleton覆盖默认注册,因为这样做是安全的:

services.AddLocalization();
services.AddSingleton(typeof(IStringLocalizer<>), typeof(StringLocalizer<>));
services.AddLocalization();
服务.AddSingleton(类型化(IStringLocalizer),类型化(StringLocalizer));

well-提供原始错误消息以及与IStringLocalizer使用位置相关的代码是正确的。