ASP.NET 核心 1.1 本地化通用服务
ASP.NET Core 1.1 Localization Generic Service
我正在制作 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".
中
此应用程序中的资源文件夹适用于 "Resources/Controllers"
我的服务在命名空间 "MyControl.Services"
这个项目中的资源文件夹(同一个解决方案中的两个项目)是
"Resources/Services/Base"
我的服务文件的命名空间是"MyControl.Services.Services.Base"
说明
你说得对,问题出在通用 class 上。根据source code of ResourceManagerStringLocalizer
(it's default IStringLocalizer
implementation) - that class contains _resourceBaseName
private field. The same string also is used定位资源文件作为搜索路径参数在ResourceManager
class.
当 IStringLocalizer
被注入到封闭的泛型类型实例中时,此字段设置不正确,例如:
FooProject.Resources.Services.FooService`1[[System.Double, System.Private.CoreLib...
而不是正确的:
FooProject.Resources.Services.FooService
您可以在调试器中检查定位器 _resourceBaseName
值。这可能是一个错误,您可以在 GitHub 上打开一个关于它的问题:https://github.com/aspnet/Localization/issues.
解决方法
可以手动创建 ResourceManagerStringLocalizer
实例。我们应该从没有 csproj 文件名且没有 class 名称本身的 class 全名中获取此 baseName
部分:
完整 class 姓名:
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;
}
}
我正在制作 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".
中此应用程序中的资源文件夹适用于 "Resources/Controllers"
我的服务在命名空间 "MyControl.Services"
这个项目中的资源文件夹(同一个解决方案中的两个项目)是
"Resources/Services/Base"
我的服务文件的命名空间是"MyControl.Services.Services.Base"
说明
你说得对,问题出在通用 class 上。根据source code of ResourceManagerStringLocalizer
(it's default IStringLocalizer
implementation) - that class contains _resourceBaseName
private field. The same string also is used定位资源文件作为搜索路径参数在ResourceManager
class.
当 IStringLocalizer
被注入到封闭的泛型类型实例中时,此字段设置不正确,例如:
FooProject.Resources.Services.FooService`1[[System.Double, System.Private.CoreLib...
而不是正确的:
FooProject.Resources.Services.FooService
您可以在调试器中检查定位器 _resourceBaseName
值。这可能是一个错误,您可以在 GitHub 上打开一个关于它的问题:https://github.com/aspnet/Localization/issues.
解决方法
可以手动创建 ResourceManagerStringLocalizer
实例。我们应该从没有 csproj 文件名且没有 class 名称本身的 class 全名中获取此 baseName
部分:
完整 class 姓名:
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;
}
}