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

时间:2017-06-01 17:32:06

标签: c# asp.net-core .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;
}

上面的代码将我的资源定位在&#34; Resources / Controllers / ValuesController.en-US.resx&#34;。

但是,当我尝试使用通用服务注入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;
    }
}

上面的代码并没有在资源/服务/基地/ Service.en-US.resx&#34;

找到我的资源。

关于如何做的任何想法?

---编辑

MyControl.Api(Startup.cs)

命名空间MyControl.Api

services.AddLocalization(options => options.ResourcesPath = "Resources");

此行位于&#34; MyControl.Api&#34;,位于名称空间&#34; MyControl.Api&#34;。

此应用程序中的资源文件夹适用于&#34;资源/控制器&#34;

我的服务位于名称空间&#34; MyControl.Services&#34;

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

&#34;资源/服务/基地&#34;

我的服务文件的命名空间是&#34; MyControl.Services.Services.Base&#34;

1 个答案:

答案 0 :(得分:4)

<强>解释

你是对的,问题出在泛型课上。根据{{​​1}} ResourceManagerStringLocalizer(默认IStringLocalizer实现) - 该类包含_resourceBaseName私有字段。同样的字符串source code也可以将资源文件定位为ResourceManager类中的搜索路径参数。

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

  

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

而不是正确的:

  

FooProject.Resources.Services.FooService

您可以在调试器中检查本地化程序_resourceBaseName的值。这可能是一个错误,你可以在GitHub上打开一个关于它的问题:is used

解决方法

可以手动创建ResourceManagerStringLocalizer实例。我们应该从类全名中取出baseName部分而不使用csproj文件名,并且本身没有类名:

全班名称:

  

MyCsprojFileName.AnyFolder.SubFolder.FooClass

baseName

  

AnyFolder.SubFolder

您提供的代码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;
    }
}