【问题标题】:Localization in external class libraries in ASP.NET CoreASP.NET Core 中外部类库的本地化
【发布时间】:2017-12-23 08:31:33
【问题描述】:

我有两个项目:

  • MyWebApp - ASP.NET Core Web API
  • MyServices - .NET Core 类库, 其中包含对上述项目的有用服务

如何将IStringLocalizer 的本地化添加到MyServices.resx 文件必须在哪里?

【问题讨论】:

    标签: c# dll asp.net-core .net-core asp.net-core-webapi


    【解决方案1】:

    我就是这样解决的。感谢 Popa Andrei 的回答将我引导到正确的地方。

    类库

    解决方案->右键->添加->新建项目...->.Net标准->类库->我用的名字是ResourceLibrary

    ResourceLibrary
    |- Resources
    |----- SharedResource.resx
    |----- SharedResource.he.resx
    |- SharedResource.cs
    

    SharedResource.cs 代码:

    using Microsoft.Extensions.Localization;
    
    namespace ResourceLibrary
    {
        public interface ISharedResource
        {
        }
        public class SharedResource : ISharedResource
        {
            private readonly IStringLocalizer _localizer;
    
            public SharedResource(IStringLocalizer<SharedResource> localizer)
            {
                _localizer = localizer;
            }
    
            public string this[string index]
            {
                get
                {
                    return _localizer[index];
                }
            }
        }
    }
    

    网络应用程序

    webapp项目右键->添加->引用...->检查资源库

    在你的 webapp startup.cs 中:

    using ResourceLibrary;
    ...
    
    public void ConfigureServices(IServiceCollection services) {
        ...
        services.AddLocalization(o => { o.ResourcesPath = "Resources"; });
    
        services.Configure<RequestLocalizationOptions>(options =>
                {
                    CultureInfo[] supportedCultures = new[]
                    {
                        new CultureInfo("en"),
                        new CultureInfo("he")
                    };
    
                    options.DefaultRequestCulture = new RequestCulture("en");
                    options.SupportedCultures = supportedCultures;
                    options.SupportedUICultures = supportedCultures;
                 });
         ...
         }
    
         public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
            ...
            app.UseRequestLocalization(); //before app.UseMvc()
            ...
            }
    

    在控制器中的使用示例:

     using ResourceLibrary;
     ...
    
     public class ExampleController : Controller
        {
        private readonly IStringLocalizer<SharedResource> _sharedLocalizer;
        public EmailsController(IStringLocalizer<SharedResource> sharedLocalizer)
        {
            _sharedLocalizer = sharedLocalizer;
        }
    
        [HttpGet]
        public string Get()
        {
            return _sharedLocalizer["StringToTranslate"];
        }
    

    查看示例:

    @using Microsoft.AspNetCore.Mvc.Localization
    @inject IHtmlLocalizer<ResourceLibrary.SharedResource> SharedLocalizer
    
    <p>@SharedLocalizer["StringToTranslate"]</p>
    

    【讨论】:

    • 你为什么使用 ISharedResource?
    • @Jenan 这是依赖注入的标准模式docs.microsoft.com/en-us/aspnet/core/fundamentals/…
    • 基于属性的本地化呢? (视图模型或枚举上的数据注释)
    • 很好的答案。我试过了,它适用于嵌入式资源构建操作,但它不适用于内容构建操作。你能给我一个替代方法,让这个方法适用于内容构建操作类型吗?
    • 是否可以在里面获取 ResourcePath :services.Configure(options => { CultureInfo[] supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("he" ) }; options.DefaultRequestCulture = new RequestCulture("en"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; }); ... }
    【解决方案2】:

    您可以将 .resx 文件存储在 MyServices 项目中,并创建一个基于键检索资源的方法。 为了从 MyServices 访问 IStringLocalizer,您必须安装 Microsoft.Extensions.Localization.Abstractions nuget。

    基本上本地化配置必须保留在 MyWebApp(启动类)上,但在 MyServices 上,您必须添加该 nuget 以使用 IStringLocalizer 并创建像 GetResourceValueByKey(key )。可以从任何将引用 MyServices 项目的位置调用此方法。

    使用 Microsoft.Extensions.Localization;

    命名空间全球化库 { 公共类 SharedResource:ISharedResource { 私有只读 IStringLocalizer _localizer;

    public SharedResource(IStringLocalizer<SharedResources> localizer) { _localizer = localizer; } public string GetResourceValueByKey(string resourceKey) { return _localizer[resourceKey]; } }}

    【讨论】:

      【解决方案3】:

      一个典型的解决方案是让您的 MyServices 程序集返回资源键(而不是返回要在屏幕上显示的实际资源)。您可以将 .resx 文件作为 MyWebApp 的一部分,并为每个资源键设置资源值。这样,您的 MyService 可以被各种 UI 应用程序使用,每个应用程序都有自己的资源表示。

      另一种方法是将 .resx 文件保留为 MyService 本身的一部分。 MyWebApp 可以加载其他程序集并从中读取资源文件。

      另一种选择是将资源保留为新程序集,然后再次从 MyWebApp 加载它。

      查看以下 SO 答案以获取有关如何从另一个程序集访问 .resx 文件的更多详细信息 -

      How can I read embedded .resx in different assembly

      Access strings resources from embedded .resx in dll?

      How to access another assembly's .resx?

      【讨论】:

      • 我是对的,将.resx 文件放在MyServices 的根目录中就足够了吗?返回资源键是什么意思?
      • 是的,没错。如果勾选资源文件的 Build Action,默认为 Embedded Resource。因此,只要加载 dll,它就可以使用。
      • 通过返回资源键,我的意思如下 -> 当您想从 MyServices 返回错误消息时,而不是返回完整消息“功能 x 中发生错误,情况 y 发生..” ,您只需从 MyServices 程序集中返回一个键(类似于 Error1001 或 ErrorFeatureXSituationY)。不要在其中附加任何资源文件。在 MyWebApp 中,有一个资源文件,它的键 Error1001 带有正确的错误消息。这样,您的资源文件将只在您的 MyWebApp 中。
      • 看起来很有趣,但我需要将.resx 文件包含在MyServices 中,所以我将尝试使用根目录下的文件进行变体!
      • 此解决方案和列出的链接不适用于 DotNet Core。
      猜你喜欢
      • 1970-01-01
      • 2017-01-06
      • 2016-10-16
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 2018-07-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多