ASP.NET Core 1.1本地化通用服务 [英] ASP.NET Core 1.1 Localization Generic Service

查看:187
本文介绍了ASP.NET Core 1.1本地化通用服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm making a ASP.NET Core 1.1 app and trying to setup localization.

当我在 ValuesController上创建 IStringLocalizer 的实现可以正常工作并本地化我的资源文件。

When I make on my ValuesController the implementation of IStringLocalizer it works fine and localize my resource file.

public ValuesController(IStringLocalizer<ValuesController> localizer, IService<BaseEntity> service)
{
    _localizer = localizer;
    _service = service;
}

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

The code above locate my resources at "Resources/Controllers/ValuesController.en-US.resx".

但是,当我尝试向 IStringLocalizer 注入通用服务时,它不能

But, when I try to inject the IStringLocalizer with a generic service it can't find my resource file.

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;
    }
}

上面的代码未在 Resources / Services / Base / Service.en-US.resx

The code above doesn't locate my resource at "Resources/Services/Base/Service.en-US.resx"

关于如何操作的任何想法?

Any idea on how to do it ?

---编辑

MyControl.Api(Startup.cs)

MyControl.Api (Startup.cs)

命名空间MyControl.Api

namespace MyControl.Api

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

此行位于 MyControl.Api内部,位于 MyControl.Api命名空间中。

This line is inside "MyControl.Api", with is in the namespace "MyControl.Api".

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

The resources folder in this aplication work for "Resources/Controllers"

我的服务位于名称空间 MyControl中.services

My services are in namespace "MyControl.Services"

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

The resources folder in this Project (two projects inside same solution) are

Resources /服务/基础

"Resources/Services/Base"

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

The namespace of my service file is "MyControl.Services.Services.Base"

推荐答案

说明

您是正确的,问题出在泛型类中。相应于<$ c $的源代码 c> ResourceManagerStringLocalizer (默认为 IStringLocalizer 实现)-该类包含 _resourceBaseName 私有字段。使用相同的字符串 ResourceManager 类中找到资源文件作为搜索路径参数。

You're right, the problem is in generic class. Accordingly to the source code of ResourceManagerStringLocalizer (it's default IStringLocalizer implementation) - that class contains _resourceBaseName private field. The same string also is used to locate resource files as a search path parameter in ResourceManager class.

IStringLocalizer 被注入到封闭的泛型类型实例中,该字段的设置不正确,例如:

When IStringLocalizer is injected into a closed generic type instance, this field is set incorrectly with something like:


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

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

而不是正确的一个:


FooProject.Resources.Services.FooService

FooProject.Resources.Services.FooService

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

You can check the localizer _resourceBaseName value in debugger. It's probably a bug and you would open an issue about it on GitHub: https://github.com/aspnet/Localization/issues.

解决方法

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

It is possible to create a ResourceManagerStringLocalizer instance manually. We should take this baseName part from a class full name without a csproj-file name and without a class name itself:

完整类名:


MyCsprojFileName.AnyFolder.SubFolder.FooClass

MyCsprojFileName.AnyFolder.SubFolder.FooClass

baseName


AnyFolder.SubFolder

AnyFolder.SubFolder

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

For the code you provided baseName is probably "Services.Base". Let's write some code to get it in generic way:

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;
    }
}

这篇关于ASP.NET Core 1.1本地化通用服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆