You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何扩展Localizer支持单语言下的细分.resx资源文件?

扩展Localizer支持单语言下的细分资源文件方案

当然可以扩展Localizer来支持这种单语言下的细分资源文件需求!而且这是最贴合.NET本地化框架规范的做法,下面我给你详细拆解实现步骤:

一、核心思路:扩展资源解析逻辑

默认的ResourceManagerStringLocalizer是按{ResourceName}.{CultureName}.resx格式查找资源的,我们需要修改这个规则,让它能识别LangaugeResource.en-GB.north.resx这类带细分后缀的文件——本质是把"north/south"作为自定义文化细分标识融入本地化流程。

二、具体实现步骤

1. 自定义StringLocalizerProvider

我们需要实现自己的IStringLocalizerProvider,重写资源查找逻辑,支持解析带细分后缀的文件名:

public class RegionalStringLocalizerProvider : IStringLocalizerProvider
{
    private readonly IResourceNamesCache _resourceNamesCache = new ResourceNamesCache();
    private readonly IHttpContextAccessor _httpContextAccessor;

    public RegionalStringLocalizerProvider(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public IStringLocalizer Create(Type resourceSource)
    {
        var assemblyName = new AssemblyName(resourceSource.Assembly.FullName!);
        var baseName = resourceSource.FullName!;
        return new ResourceManagerStringLocalizer(
            new ResourceManager(baseName, resourceSource.Assembly),
            resourceSource,
            _resourceNamesCache,
            GetRegionalCultureInfo());
    }

    public IStringLocalizer Create(string baseName, string location)
    {
        var assembly = Assembly.Load(new AssemblyName(location));
        return new ResourceManagerStringLocalizer(
            new ResourceManager(baseName, assembly),
            assembly,
            baseName,
            _resourceNamesCache,
            GetRegionalCultureInfo());
    }

    // 根据业务逻辑获取当前细分区域(示例从请求头取,也可从会话/用户配置读取)
    private CultureInfo GetRegionalCultureInfo()
    {
        var httpContext = _httpContextAccessor.HttpContext;
        var region = httpContext?.Request.Headers["X-Region"].FirstOrDefault() ?? "north";
        
        var currentCulture = CultureInfo.CurrentCulture;
        var regionalCultureName = $"{currentCulture.Name}.{region}";
        // 创建自定义细分文化,若系统未注册则自动生成
        return CultureInfo.CreateSpecificCulture(regionalCultureName);
    }
}

2. 替换默认本地化服务配置

在Program.cs中注册自定义Provider,替换默认实现:

builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");

// 注册HttpContextAccessor用于获取请求上下文
builder.Services.AddHttpContextAccessor();
// 替换默认的StringLocalizerProvider为自定义区域化Provider
builder.Services.AddSingleton<IStringLocalizerProvider, RegionalStringLocalizerProvider>();

builder.Services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new[]
    {
        new CultureInfo("en-GB"),
        new CultureInfo("cy"),
        // 添加带细分的自定义文化
        new CultureInfo("en-GB.north"),
        new CultureInfo("en-GB.south")
    };

    options.DefaultRequestCulture = new RequestCulture("en-GB");
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;
});

3. 创建细分资源文件

按规则创建对应资源文件:

  • LangaugeResource.en-GB.north.resx(英式英语北部版本)
  • LangaugeResource.en-GB.south.resx(英式英语南部版本)
  • 保留原LangaugeResource.en-GB.resx作为回退(细分资源找不到键时,自动用父级文化的资源)

4. 业务代码中使用

和原有Localizer用法完全一致,框架会自动加载对应细分区域的资源:

private readonly IStringLocalizer<LangaugeResource> _localizer;

public HomeController(IStringLocalizer<LangaugeResource> localizer)
{
    _localizer = localizer;
}

public IActionResult Index()
{
    var buttonText = _localizer["SubmitButton"];
    return View(buttonText);
}

三、备选方案:不扩展Localizer的实现

如果不想修改框架核心逻辑,也可以用自定义资源加载器:

  • 手动读取指定细分目录的resx文件
  • 编写RegionalResourceLoader服务,根据当前区域标识加载对应键值对
  • 这种方式更灵活,但需要自己处理缓存、回退逻辑,不如扩展Localizer贴合框架生态

内容的提问来源于stack exchange,提问作者Dave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:58:24