如何将IStringLocalizer注入IApplicationModelConvention?

时间:2018-12-20 13:45:37

标签: asp.net-mvc asp.net-core .net-core

我有一个自定义约定,该约定要求在其中包含本地化字符串。 AFAIK实例化IStringLocalizer的唯一方法是DependencyInjection。

如何在CustomConvention内使用IStringLocalizer?

约定是这样注册的

public void ConfigureServices(IServiceCollection services)
{
     //First I register the localization settings
     services.AddLocalization(o =>
     {
        o.ResourcesPath = "Resources";
     });

      services.AddMvc(options =>
      {
           //My custom convention, I would need to inject an IStringLocalizer  
           //into constructor here, but I can' instantiate it
           options.Conventions.Add(new LocalizationRouteConvention());
      })
}

2 个答案:

答案 0 :(得分:3)

我的解决方案并不漂亮。

您可以执行类似的操作,构建服务提供程序以获取StringLocalizer的实例。

public void ConfigureServices(IServiceCollection services)
{
     //First I register the localization settings
     services.AddLocalization(o =>
     {
        o.ResourcesPath = "Resources";
     });

     var stringLocalizer = services.BuildServiceProvider().GetService<IStringLocalizer<Resource>>();

     services.AddMvc(options =>
     {
          //My custom convention, I would need to inject an IStringLocalizer  
          //into constructor here, but I can' instantiate it
          options.Conventions.Add(new LocalizationRouteConvention(stringLocalizer));
     })
}

答案 1 :(得分:0)

我建议采用此处提供的方法 https://stackoverflow.com/a/61958762/4627333

您基本上只需要注册您的类型并创建一个 IConfigureOptions<MvcOptions> 的实现,期待您的约定实现。 DI 将完成剩下的工作。

public class LocalizationRouteConventionMvcOptions : IConfigureOptions<MvcOptions>
{
    private readonly LocalizationRouteConvention _convention;

    public MyMvcOptions(LocalizationRouteConvention convention)
        => _convention = convention;

    public void Configure(MvcOptions options)
        => options.Conventions.Add(_convention);
}

public void ConfigureServices(IServiceCollection services)
{
    // or scoped, or transient, as necessary for your service
    services.AddTransient<IStringLocalizer<Resource>, MyStringLocalizer>();
    services.AddSingleton<LocalizationRouteConvention>();
    services.AddSingleton<IConfigureOptions<MvcOptions>, LocalizationRouteConventionMvcOptions>();

    services.AddControllers();
}

您的 LocalizationRouteConvention 代码:

public sealed class LocalizationRouteConvention : IApplicationModelConvention
{
    private readonly IStringLocalizer<Resource> _stringLocalizer;

    public LocalizationRouteConvention(IStringLocalizer<Resource> stringLocalizer)
    {
        _stringLocalizer = stringLocalizer ?? throw new ArgumentNullException(nameof(stringLocalizer));
    }

    public void Apply(ApplicationModel application)
    {
        // ...
    }
}