我在ASP.NET core 2.1中拥有一个ASP.NET Web api,并且已经实现了共享资源,如here所述。效果很好。
该行:
services.AddLocalization()
将本地化添加到内置的IOC容器中。 (我认为这至少是魔术发生的地方)
现在,我已经为自己的类添加了Simple Injector到混合物中,并且我有一个已注册为Async Scoped的类,该类通过共享资源(通过IStringLocalizer)注入。但是,IStringLocalizer的作用域范围是瞬态的,并且与Async Scoped不兼容(因为它的作用域更长)。我可以通过将选项“ SuppressLifestyleMismatchVerification” 设置为true来解决该问题,但这听起来不对。 (在这种情况下,可能没有关系,但是通过使用此选项,我掩盖了我可能遇到的其他问题)是否有解决此问题的方法?例如,我可以更改共享资源的范围吗?
答案 0 :(得分:1)
您看到的是两个宇宙碰撞;这两个DI库都有它们自己的,不兼容的定义,这些定义是 transient :
Transient
的组件寿命短,即简短。这就是为什么简单注入器不允许将瞬态注入到范围内的组件中的原因;望远镜的寿命可能比简短的时间更长。Transient
组件的预期生存期应为,只要其使用者的预期生存期为即可。 docs甚至声明“此生命期最适合轻量级,无状态服务。” 正是由于这种行为,Microsoft.Extensions.DependencyInjection(MS.DI)容器允许将瞬态注入到单例和范围内的使用者中。
我什至会认为Microsoft错误地命名了他们的生活方式,因为实际行为是每个消费者的依存关系只有一个实例。 Microsoft似乎已经从Autofac复制了此行为。但是,如果您问我,Autofac确实会命名相同的生活方式InstancePerDependency
,这是一个明显得多的名字。
不过,奇怪的是,Microsoft的AddLocalization
扩展方法registers StringLocalizer<T>
是短暂的。这很奇怪,因为除了包装的IStringLocalizer
之外,StringLocalizer<T>
没有任何状态。不仅如此,它包装的IStringLocalizer
是由注入的IStringLocalizerFactory
产生的,并且可以预期是同一实例(这是由于ResourceManagerStringLocalizerFactory
{{3 }}返回的实例。
如上所述,在MS.DI中,Transient
的意思是“我的寿命与消费者的寿命一样长。 “实际上,这意味着StringLocalizer<T>
实例可以存在一个单例,这意味着:在整个应用程序期间。
从这方面来说,本地化团队选择StringLocalizer<T>
来拥有短暂的生活方式实际上是很奇怪的,即使在MS.DI中也是如此。瞬态仅意味着创建了更多实例,并且IStringLocalizerFactory
的调用次数比所需次数更多。我发现Singleton
的注册方式更为明显。
长话短说,我建议覆盖一个单例的默认注册,因为这样做还是很安全的:
services.AddLocalization();
services.AddSingleton(typeof(IStringLocalizer<>), typeof(StringLocalizer<>));