带有第三方 DI 的 IStringLocalizer
IStringLocalizer with third party DI
我正在尝试按照此文档设置本地化
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization
我假设如果您使用内置 DI,它就可以正常工作,但是我使用的是 Simple Injector 而不是内置 DI,所以它抱怨我没有注册 IStringLocalizer。我该如何注册 IStringLocalizer,因为我显然不能这样做
container.Register<IStringLocalizer, StringLocalizer>(Lifestyle.Scoped);
谢谢
要在 ASP.NET Core 中进行本地化,您必须从 ConfigureServices
方法中调用 AddLocalization()
并启用 自动交叉连接:
public void ConfigureServices(IServiceCollection services) {
services.AddLocalization(); // ** Add localization to ASP.NET Core **
// Normal MVC stuff
services.AddMvc();
// Simple Injector integration
IntegrationSimpleInjector(services);
}
private void IntegrationSimpleInjector(IServiceCollection services) {
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IControllerActivator>(
new SimpleInjectorControllerActivator(container));
services.EnableSimpleInjectorCrossWiring(container);
services.UseSimpleInjectorAspNetRequestScoping(container);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
// This call allows Simple Injector to resolve anything from ASP.NET Core.
container.AutoCrossWireAspNetComponents(app); // ** Enable auto cross-wiring ***
// NOTE: If you're still running .NET Core v1.x, auto cross-wiring will not be
// available. In that case, you can make the following call to CrossWire<T>
// to register StringLocalizer<T>'s dependency explicitly.
// container.CrossWire<IStringLocalizerFactory>(app);
// Your usual startup stuff here
}
对 services.AddLocalization()
的调用添加了对 ASP.NET 核心配置系统的适当注册,但它本身并不允许 Simple Injector 访问它。然而,Simple Injector v4.1 包含一个 AutoCrossWireAspNetComponents
扩展方法,允许容器在 ASP.NET 核心配置系统中寻找缺失的依赖项。
这就是你需要的一切,运行,但我们可以做得更好...
由于内置 ASP.NET 核心 DI 容器的限制,您被迫注入通用抽象,例如 ILogger<T>
和 IStringLocalizer<T>
,其中 T
将 总是 是消费类型本身。这意味着当 HomeController
中需要这种依赖时,你需要注入一个 ILogger<HomeController>
和 IStringLocalizer<HomeController>
。能够注入非泛型 ILogger
和 IStringLocalizer
抽象,并让 DI 容器自动找到正确的泛型实现来实现,这将更加清洁、更易于维护和更安全。
不幸的是,内置的 DI 容器不支持这个。但是大多数成熟的 DI 库实际上 确实 支持这一点,Simple Injector 也是如此。
以下注册,允许任何应用程序组件依赖于非泛型 IStringLocalizer
并且 Simple Injector 将注入泛型 StringLocalizer<T>
,其中 T
成为消费类型,因此仍然获取 那个特定 class.
的定位器
container.RegisterConditional(
typeof(IStringLocalizer),
c => typeof(StringLocalizer<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
c => true);
通过此注册,您的 HomeController
将不再依赖 IStringLocalizer
,如下所示:
public class HomeController : Controller
{
private readonly IStringLocalizer localizer;
public HomeController(IStringLocalizer localizer)
{
this.localizer = localizer;
}
}
我知道这是旧的,但我遇到了这个 post 想做同样的事情,但我根据我使用的 ILogger 注册采取了不同的方法。所以这就是我在我的控制器和服务中获得强类型 IStringLocalizers 的方法。
Cross-wire StringLocalizerFactory
container.CrossWire<IStringLocalizerFactory>(app);
然后使用RegisterConditional
container.RegisterConditional(
typeof(IStringLocalizer),
c => typeof(StringLocalizer<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
c => true);
然后我可以将 non-generic IStringLocalizer 注入我的控制器等,它将是正确的类型。例如,如果我使用以下构造函数
public MyController(IStringLocalizer localiser)...
那么 localiser 的类型将是
IStringLocalizer<MyController>
这是 ASP.NET Core MVC 2 & Simple Injector 4.1。不知steven对这种做法有何评论?
我正在尝试按照此文档设置本地化
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization
我假设如果您使用内置 DI,它就可以正常工作,但是我使用的是 Simple Injector 而不是内置 DI,所以它抱怨我没有注册 IStringLocalizer。我该如何注册 IStringLocalizer,因为我显然不能这样做
container.Register<IStringLocalizer, StringLocalizer>(Lifestyle.Scoped);
谢谢
要在 ASP.NET Core 中进行本地化,您必须从 ConfigureServices
方法中调用 AddLocalization()
并启用 自动交叉连接:
public void ConfigureServices(IServiceCollection services) {
services.AddLocalization(); // ** Add localization to ASP.NET Core **
// Normal MVC stuff
services.AddMvc();
// Simple Injector integration
IntegrationSimpleInjector(services);
}
private void IntegrationSimpleInjector(IServiceCollection services) {
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IControllerActivator>(
new SimpleInjectorControllerActivator(container));
services.EnableSimpleInjectorCrossWiring(container);
services.UseSimpleInjectorAspNetRequestScoping(container);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
// This call allows Simple Injector to resolve anything from ASP.NET Core.
container.AutoCrossWireAspNetComponents(app); // ** Enable auto cross-wiring ***
// NOTE: If you're still running .NET Core v1.x, auto cross-wiring will not be
// available. In that case, you can make the following call to CrossWire<T>
// to register StringLocalizer<T>'s dependency explicitly.
// container.CrossWire<IStringLocalizerFactory>(app);
// Your usual startup stuff here
}
对 services.AddLocalization()
的调用添加了对 ASP.NET 核心配置系统的适当注册,但它本身并不允许 Simple Injector 访问它。然而,Simple Injector v4.1 包含一个 AutoCrossWireAspNetComponents
扩展方法,允许容器在 ASP.NET 核心配置系统中寻找缺失的依赖项。
这就是你需要的一切,运行,但我们可以做得更好...
由于内置 ASP.NET 核心 DI 容器的限制,您被迫注入通用抽象,例如 ILogger<T>
和 IStringLocalizer<T>
,其中 T
将 总是 是消费类型本身。这意味着当 HomeController
中需要这种依赖时,你需要注入一个 ILogger<HomeController>
和 IStringLocalizer<HomeController>
。能够注入非泛型 ILogger
和 IStringLocalizer
抽象,并让 DI 容器自动找到正确的泛型实现来实现,这将更加清洁、更易于维护和更安全。
不幸的是,内置的 DI 容器不支持这个。但是大多数成熟的 DI 库实际上 确实 支持这一点,Simple Injector 也是如此。
以下注册,允许任何应用程序组件依赖于非泛型 IStringLocalizer
并且 Simple Injector 将注入泛型 StringLocalizer<T>
,其中 T
成为消费类型,因此仍然获取 那个特定 class.
container.RegisterConditional(
typeof(IStringLocalizer),
c => typeof(StringLocalizer<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
c => true);
通过此注册,您的 HomeController
将不再依赖 IStringLocalizer
,如下所示:
public class HomeController : Controller
{
private readonly IStringLocalizer localizer;
public HomeController(IStringLocalizer localizer)
{
this.localizer = localizer;
}
}
我知道这是旧的,但我遇到了这个 post 想做同样的事情,但我根据我使用的 ILogger 注册采取了不同的方法。所以这就是我在我的控制器和服务中获得强类型 IStringLocalizers 的方法。
Cross-wire StringLocalizerFactory
container.CrossWire<IStringLocalizerFactory>(app);
然后使用RegisterConditional
container.RegisterConditional(
typeof(IStringLocalizer),
c => typeof(StringLocalizer<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
c => true);
然后我可以将 non-generic IStringLocalizer 注入我的控制器等,它将是正确的类型。例如,如果我使用以下构造函数
public MyController(IStringLocalizer localiser)...
那么 localiser 的类型将是
IStringLocalizer<MyController>
这是 ASP.NET Core MVC 2 & Simple Injector 4.1。不知steven对这种做法有何评论?