ASP.NET Core 1.1本地化通用服务

Luc*_*tas 5 c# .net-core asp.net-core asp.net-core-localization

我正在制作一个ASP.NET Core 1.1应用程序并尝试设置本地化.

当我在我ValuesController的实现上IStringLocalizer它工作正常并本地化我的资源文件.

public ValuesController(IStringLocalizer<ValuesController> localizer, IService<BaseEntity> service)
{
    _localizer = localizer;
    _service = service;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码在"Resources/Controllers/ValuesController.en-US.resx"中找到我的资源.

但是,当我尝试注入IStringLocalizer一个通用服务时,它无法找到我的资源文件.

public class Service<T> : IService<T>
    where T : BaseEntity
{
    #region Properties
    protected IRepository Repository { get; set; }
    protected IUnitOfWorkFactory UnitOfWorkFactory { get; set; }
    private readonly ILogger _logger;
    private readonly IStringLocalizer _localizer;

    #endregion

    #region Ctor
    public Service(IRepository repository, IUnitOfWorkFactory unitOfWorkFactory,
        ILogger<Service<T>> logger, IStringLocalizer<Service<T>> localizer)
    {
        Repository = repository;
        UnitOfWorkFactory = unitOfWorkFactory;
        _logger = logger;
        _localizer = localizer;
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码没有找到我的资源"Resources/Services/Base/Service.en-US.resx"

有什么想法怎么做?

---编辑

MyControl.Api(Startup.cs)

命名空间MyControl.Api

services.AddLocalization(options => options.ResourcesPath = "Resources");
Run Code Online (Sandbox Code Playgroud)

这一行在"MyControl.Api"中,位于名称空间"MyControl.Api"中.

此应用程序中的资源文件夹适用于"资源/控制器"

我的服务在名称空间"MyControl.Services"中

此项目中的资源文件夹(同一解决方案中的两个项目)是

"资源/服务/基地"

我的服务文件的命名空间是"MyControl.Services.Services.Base"

Ily*_*kov 6

解释

你是对的,问题出在通用类中。根据(它的默认实现)的源代码- 该类包含私有字段。相同的字符串还用于作为类中的搜索路径参数来定位资源文件。ResourceManagerStringLocalizerIStringLocalizer_resourceBaseNameResourceManager

IStringLocalizer注入到封闭泛型类型实例中时,该字段设置不正确,如下所示:

FooProject.Resources.Services.FooService`1[[System.Double, System.Private.CoreLib...

而不是正确的一个:

FooProject.Resources.Services.FooService

您可以_resourceBaseName在调试器中检查定位器值。这可能是一个错误,您可以在 GitHub 上打开一个有关它的问题: https: //github.com/aspnet/Localization/issues

解决方法

可以ResourceManagerStringLocalizer手动创建实例。baseName我们应该从没有 csproj 文件名且没有类名本身的类全名中获取这部分:

完整班级名称:

MyCsprojFileName.AnyFolder.SubFolder.FooClass

baseName

任意文件夹.子文件夹

对于您提供的代码baseName可能是"Services.Base". 让我们编写一些代码以通用方式获取它:

public class FooService<T>
{
    private readonly IStringLocalizerFactory _factory;

    public FooService(IStringLocalizerFactory factory)
    {
        _factory = factory;
    }

    public IStringLocalizer GetLocalizer()
    {
        var type = typeof(FooService<>);

        string assemblyName = type.GetTypeInfo().Assembly.GetName().Name;
        string typeName = type.Name.Remove(type.Name.IndexOf('`'));
        string baseName = (type.Namespace + "." + typeName).Substring(assemblyName.Length).Trim('.');

        var localizer = _factory.Create(baseName, assemblyName);

        return localizer;
    }
}
Run Code Online (Sandbox Code Playgroud)