.net - asp.net core 2.1 中的共享资源本地化和简单注入(inject)器

标签 .net asp.net-core dependency-injection localization simple-injector

我在 ASP.NET core 2.1 中有一个 ASP.NET Web api,并且我已经实现了一个共享资源,如 here 所解释的那样。 。这工作得很好。

行:

services.AddLocalization()

向内置 IOC 容器添加本地化。 (我认为这至少是魔法发生的地方)

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

最佳答案

TLDR;覆盖默认注册,如下所示:

services.AddLocalization();
services.AddSingleton(typeof(IStringLocalizer<>), typeof(StringLocalizer<>));

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

  • 简单注入(inject)器考虑具有 Transient 的组件生活方式是短暂的,或者短暂。这就是为什么 Simple Injector 不允许将 transient 注入(inject)到 Singleton 组件中; Singleton 的生存时间可能比被认为短暂的时间长得多。

    v5 之前的简单注入(inject)器版本(OP 正在使用的)也限制将 transient 服务注入(inject)到作用域组件中。然而,随着 v5 的引入,这种行为有所放松,这意味着现在可以(默认情况下)将 transient 注入(inject)到作用域组件中。但是, transient 仍然不能注入(inject)到单例中。

  • ASP.NET Core/MS.DI 根本不认为 transient 组件是短暂的。。相反,Transient 的预期生命周期.NET Core 中的组件与其使用者的预期生命周期一样长docs甚至指出“此生命周期最适合轻量级、无状态服务。”

正是由于这种行为,Microsoft.Extensions.DependencyInjection (MS.DI) 容器才允许将 transient 注入(inject)到单例和作用域使用者中。

SIDE NOTE: I would even argue that Microsoft named their lifestyle incorrectly, because the actual behavior is to have one instance per consumer's dependency. Microsoft seems to have copied this behavior from Autofac. Autofac, however, does name this same lifestyle InstancePerDependency, which is a much more obvious name, if you ask me.

奇怪的是,微软的 AddLocalization扩展方法registers StringLocalizer<T>作为 transient 。这很奇怪,因为除了包裹的 IStringLocalizer , StringLocalizer<T>没有任何状态。不仅如此,IStringLocalizer它包装的内容是由注入(inject)的 IStringLocalizerFactory 生成的并且可以预期是同一个实例(这是由于 ResourceManagerStringLocalizerFactory caches 返回实例而强制执行的)。

如上所述,在 MS.DI 中,Transient意思是“我会和我的消费者一样长寿。 “这实际上意味着 StringLocalizer<T>实例可以与单例一样长地存在,这意味着:在整个应用程序的持续时间内。

从这个方面来看,本地化团队选择 StringLocalizer<T> 实际上确实很奇怪。拥有短暂的生活方式,即使是在 MS.DI。 transient 仅意味着创建了更多实例,而 IStringLocalizerFactory调用的次数超出了需要的次数。我找到Singleton该注册的生活方式更加明显。

因此,我建议覆盖使用单例的默认注册,因为无论如何这样做都是安全的:

services.AddLocalization();
services.AddSingleton(typeof(IStringLocalizer<>), typeof(StringLocalizer<>));

关于.net - asp.net core 2.1 中的共享资源本地化和简单注入(inject)器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53192683/

相关文章:

.NET 3.5图表控件异常: Error executing child request for ChartImg. axd

asp.net - 如何在错误的 .NET Core API 路由上抛出 404?

javascript - 使用 javascript 获取 AspNet.ApplicationCookie

.net - 有人可以给我一个真实世界的例子,说明我可能想要/需要在 .NET 中使用 BitArray 类吗?

.net - Office 插件的前向兼容性

c# - 传递给 MVC Controller 的 id 总是映射为 0

c# - 如何在 ASP.NET Core 中结合基于模板和属性的路由?

php - 将全局数据库连接传递到模型的每个函数中有什么好处?

c# - 如何为使用包装器的 Azure Functions 编写单元测试?

ios - 如何使用依赖注入(inject)和工厂模式实现 ViewController 自定义初始化?