2017-06-01 79 views
4

我正在制作ASP.NET Core 1.1应用程序并尝试设置本地化。ASP.NET核心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; 
    } 
} 

上面的代码并没有在“资源/服务/基/ Service.en-US.resx”

找到我的资源上如何做到这一点任何想法?

--- EDIT

MyControl.Api(Startup.cs)

命名空间MyControl.Api

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

这条线是内部 “MyControl.Api”,用的是命名空间中的“MyControl.Api”。

在“资源/控制器”

我的服务是命名空间“MyControl.Services”

在这个项目中的资源文件夹(同一个解决方案中的两个项目)这个aplication工作的资源文件夹是

“资源/服务/基地”

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

+0

默认情况下,如果路径资源文件是正确的它应该工作。请添加服务的名称空间和您的'services.AddLocalization'调用问题。 –

+0

已添加。 Service.cs命名空间>“MyControl.Services.Services.Base” “MyControl.Services”项目中的资源文件夹“Resources/Services/Base” –

回答

3

说明

你说得对,问题在于泛型类。根据source codeResourceManagerStringLocalizer(它的默认IStringLocalizer实施) - 该类别包含_resourceBaseName专用字段。相同的字符串is used可将资源文件定位为ResourceManager类中的搜索路径参数。

IStringLocalizer被注入封闭的通用类型的实例,该字段与类似设置不正确:

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

而不是正确的:

FooProject.Resources.Services.FooService

您可以在调试器中检查本地化器_resourceBaseName的值。这可能是一个bug,你会在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; 
    } 
} 
+0

为了避免每个类的“必须拥有”资源并因此重复消息我创建了一个持有者类“LanguageLocalizer.cs”,并从中初始化所有我的本地化器。但是,你的意思是对的。非常感谢你 ! –