Базовая служба локализации ASP.NET Core 1.1

Я делаю приложение ASP.NET Core 1.1 и пытаюсь настроить локализацию.

Когда я делаю на моем ValuesController реализация IStringLocalizer он отлично работает и локализует мой файл ресурсов.

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

Код выше найти мои ресурсы в "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;
    }
}

Приведенный выше код не находит мой ресурс по адресу "Resources/Services/Base/Service.en-US.resx"

Есть идеи, как это сделать?

--- РЕДАКТИРОВАТЬ

MyControl.Api (Startup.cs)

Пространство имен MyControl.Api

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

Эта строка находится внутри "MyControl.Api", а находится в пространстве имен "MyControl.Api".

Папка ресурсов в этой заявке работает для "Ресурсы / Контроллеры"

Мои сервисы находятся в пространстве имен "MyControl.Services"

Папка ресурсов в этом проекте (два проекта в одном решении)

"Ресурсы / Услуги /Base"

Пространство имен моего служебного файла - "MyControl.Services.Services.Base".

1 ответ

Решение

объяснение

Вы правы, проблема в общем классе. В соответствии с исходным кодом ResourceManagerStringLocalizer (это по умолчанию IStringLocalizer реализация) - этот класс содержит _resourceBaseName личное поле. Эта же строка также используется для поиска файлов ресурсов в качестве параметра пути поиска в ResourceManager учебный класс.

когда 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:

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;
    }
}
Другие вопросы по тегам