带有第三方 DI 的 IStringLocalizer

Mic*_*ves 4 simple-injector asp.net-core-localization

我正在尝试按照此文档设置本地化

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization

我假设如果你使用内置的 DI,它就可以工作,但是我使用的是 Simple Injector 而不是内置的 DI,所以它抱怨我没有注册 IStringLocalizer。我如何注册 IStringLocalizer 因为我显然不能这样做

container.Register<IStringLocalizer, StringLocalizer>(Lifestyle.Scoped);
Run Code Online (Sandbox Code Playgroud)

谢谢

Ste*_*ven 5

要在 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
}
Run Code Online (Sandbox Code Playgroud)

调用services.AddLocalization()将适当的注册添加到 ASP.NET Core 配置系统,但这本身并不允许 Simple Injector 访问它。然而,Simple Injector v4.1 包含一个AutoCrossWireAspNetComponents扩展方法,允许容器在 ASP.NET Core 配置系统中查找缺失的依赖项。

这就是您启动和运行所需的全部内容,但我们可以做得更好......

由于内置 ASP.NET Core DI 容器的限制,您被迫注入泛型抽象,例如ILogger<T>IStringLocalizer<T>whereT始终是消费类型本身。这意味着当在 中HomeController需要这种依赖时,您需要注入一个ILogger<HomeController>IStringLocalizer<HomeController>。能够注入非泛型ILoggerIStringLocalizer抽象,并让 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);
Run Code Online (Sandbox Code Playgroud)

通过此注册,您HomeController可以不依赖于IStringLocalizer如下所示:

public class HomeController : Controller
{
    private readonly IStringLocalizer localizer;

    public HomeController(IStringLocalizer localizer)
    {
        this.localizer = localizer;
    }
}
Run Code Online (Sandbox Code Playgroud)