.NET Core - 全球化和本地化 - 类库

5
根据.NET Core的全球化和本地化实现文档this,我的目标是将所有资源存储在一个位于不同项目(类库)中的全局资源文件中。 项目1 - Startup.cs
public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

        if (env.IsEnvironment("Development"))
        {
            builder.AddApplicationInsightsSettings(developerMode: true);
        }

        builder.AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddApplicationInsightsTelemetry(Configuration);

        services.AddLocalization(lo => lo.ResourcesPath = "/MYCLASSLIBRARY"); //External project ~ How?

        services.AddMvc(config =>
        {
            var policy = new AuthorizationPolicyBuilder()
                             .RequireAuthenticatedUser()
                             .Build();
            config.Filters.Add(new AuthorizeFilter(policy));
        });

        services.Configure<RequestLocalizationOptions>(
            opts =>
            {
                var supportedCultures = new List<CultureInfo>
                {
                    new CultureInfo("en-US"),
                    new CultureInfo("sv-SE")
                };

                opts.DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US");
                opts.SupportedCultures = supportedCultures;
                opts.SupportedUICultures = supportedCultures;
            });
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRequestLocalization(app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>().Value);

        app.UseMvc();

        app.UseDefaultFiles();

        app.UseStaticFiles();
    }
}

项目2 - 类库

enter image description here

项目1 - 控制器

using MYCLASSLIBRARY; //External project

[Route("api/[controller]")]
public class HelloController : Controller
{
    private readonly IStringLocalizer<Test> _localizer; //External project class

    public OrganisationController(IStringLocalizer<Test> localizer)
    {
        _mapper = mapper;

        _localizer = localizer;
    }

    [HttpGet("GetResource")]
    public string GetResource()
    {
        return _localizer["Help"];
    }
}

如何在设置ResourcesPath时引用外部项目?
services.AddLocalization(lo => lo.ResourcesPath = "/MYCLASSLIBRARY");

我不是想通过编程来构建资源,我只想在启动文件中注册外部资源 :) 使用单独的程序集的原因是因为我希望能够从多个项目中使用相同的资源,例如从Web.WebApi或我的中间层Business.WebService中检索资源(两个不同的项目)。这两个项目都将引用资源类库。 - Reft
你的“另一个答案”是一个五年前的问题。我在mvc 5及以下版本中实现外部资源时没有遇到任何问题。“虽然在ASP.NET Core中每个文化的.resx文件的概念仍然存在,但资源的使用方式发生了相当大的变化。在以前的版本中,当你向解决方案添加.resx文件时,会创建一个设计器文件,通过调用Resources.MyTitleString等静态强类型访问提供对资源的访问。” - Reft
好的。我现在明白了。但是,我想问一下你的DAL是否需要处理这个责任。最终,你的UI/WebApi层可能是呈现应该发生的地方。我知道你在做什么,但是如果将所有本地化/呈现移动到它所属的层中,你可以简化事情。 - trevorc
好的,我明白你的意思,但是想象一下,如果我的数据访问层中有100个SendEmail函数的邮件服务。如果我将资源处理移动到Web层中,那么会非常混乱。我需要在Web层中构建某种额外的EmailService来创建不同的电子邮件格式,然后将其传递给数据访问层...也许这样做更好,但我不确定。 - Reft
好主意。但是,如果您的要求如此之大,那么也许您应该考虑一些事件总线。电子邮件服务不应该与您的数据访问层(DAL)有任何关系。触发带有本地化令牌的事件到一个单独的服务(微服务)进行处理。我知道这很难。我只是发现,与您的要求匹配的架构通常会解决问题。过度优化只会导致头发掉光。祝你好运! - trevorc
显示剩余3条评论
1个回答

2
如果您还没有想清楚,这里有一个简单的方法可以在当前配置中完成。只需将以下行替换为:

services.AddLocalization(lo => lo.ResourcesPath = "/MYCLASSLIBRARY"); //外部项目 ~ 怎么做? 使用以下代码:

services.AddLocalization(); //移除目标程序集中的根文件夹,因此它将在您的MYCLASSLIBRARY程序集的根目录中查找该文件

或者

将资源文件移动到“MYCLASSLIBRARY”文件夹下。只要定义ResourcesPath时不删除前导'/'。

希望对您有所帮助。


谢谢,它帮助了我。 - graycrow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接