我尝试按照此文档设置本地化
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization
我认为如果你使用内置DI它只是工作,但是我使用Simple Injector而不是在DI中构建,所以它抱怨我没有注册IStringLocalizer。我如何注册IStringLocalizer,因为我显然无法做到这一点
container.Register<IStringLocalizer, StringLocalizer>(Lifestyle.Scoped);
由于
答案 0 :(得分:3)
要在ASP.NET Core中使用本地化,您必须在AddLocalization()
方法中调用ConfigureServices
并启用自动交叉连接:
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 Core配置系统的适当注册,但是它本身不允许Simple Injector到达它。然而,Simple Injector v4.1包含一个AutoCrossWireAspNetComponents
扩展方法,允许容器在ASP.NET Core配置系统中查找缺少的依赖项。
这就是你需要做的事情,但我们可以做得更好......
由于内置ASP.NET Core DI容器的限制,您必须注入ILogger<T>
和IStringLocalizer<T>
这样的通用抽象,其中T
将始终< / em>是消费类型本身。这意味着当HomeController
中需要这种依赖时,您需要注入ILogger<HomeController>
和IStringLocalizer<HomeController>
。能够注入非通用ILogger
和IStringLocalizer
抽象,并且让DI容器自动找到要实现的正确通用实现,它会更清晰,更易于维护和更安全。
不幸的是,内置的DI容器不支持这个。但是,大多数成熟的DI库实际上做支持这一点,就像Simple Injector一样。
以下注册允许任何应用程序组件依赖于非泛型IStringLocalizer
,而Simple Injector将注入通用StringLocalizer<T>
,其中T
成为消费类型,因此仍然获得特定类的本地化程序。
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;
}
}
答案 1 :(得分:1)
我知道这已经过时了,但是我发现这篇文章的目的是做同样的事情,但我根据我使用的ILogger注册采取了不同的方法。所以这就是我在控制器和服务中获得强类型IStringLocalizers的方法。
交叉连接StringLocalizerFactory
container.CrossWire<IStringLocalizerFactory>(app);
然后使用RegisterConditional
container.RegisterConditional(
typeof(IStringLocalizer),
c => typeof(StringLocalizer<>).MakeGenericType(c.Consumer.ImplementationType),
Lifestyle.Singleton,
c => true);
然后我可以将非通用IStringLocalizer注入我的控制器等,它将是正确的类型。例如,如果我使用以下构造函数
public MyController(IStringLocalizer localiser)...
然后localiser将是
类型IStringLocalizer<MyController>
这是ASP.NET Core MVC 2&amp;简单的注射器4.1。我想知道steven是否对此方法有任何评论?