Dotnet选项模式的全球化与本地化

前言

选项模式 Options 是Dotnet非常重要的一个基础概念,在应用开发过程中很多Service都关联着其 Options。

我们有个AI Agent使用 Options 来配置AI的一部分功能,原需求是只需要支持英文语言,现需求改为要支持其它共6种语言。我决定开发一个类库,使 Options 完整地得到多语言支持。

设计思路

1 具体语言的Configuration

使用OptionsLocalization:{OptionsName}:{culture}做为配置的key前缀,例如AIOptions选项的ModelId属性,在配置里的zh-CN对应的keyOptionsLocalization:AIOptions:zh-CN:ModelId

2 简化的 json 配置文件

未简化前的 AIOptions/zh-CN.json

/* by yours.tools - online tools website : yours.tools/zh/calctime.html */
{
	"OptionsLocalization": {
		"AIOptions": {
			"zh-CN": {
				"ModelId": "gemini2.5",
                "Prompt": "你好世界"
			}
		}
	}
}

期待简化后的 AIOptions/zh-CN.json

/* by yours.tools - online tools website : yours.tools/zh/calctime.html */
{	 
	"ModelId": "gemini2.5",
    "Prompt": "你好世界"
}
3 语言区域别名化的 Options
// 选项绑定到别名化的配置
// 如果是默认语言区域,则注册成别名为Options.DefaultName
services.Configure<AIOptions>("zh-CN", configuration.GetSection("OptionsLocalization:AIOptions:zh-CN"));
// 使用别名获取选项
IOptionsMonitor<AIOptions>().Get("zh-CN");
4 支持父语言区域回退

假设注册"en"默认语言和zh语言

services.Configure<AIOptions>("zh", zhSection);
services.Configure<AIOptions>(Options.DefaultName, enSection);

现在前端的语言区域为"zh-CN",IOptionsMonitor<AIOptions>().Get("zh-CN")会存在以下问题:

  1. zh-CN不存在,要回退到zh-Hans
  2. zh-Hans不存在,要回退到zh
  3. zh下的ModelId没有配置项,要回退使用默认的en下的ModelId

我们需要实现自定义的IOptionsFactory<TOptions>,把指定的语言区域别名的AIOptions构建正确。

sealed class CultureOptionsFactory<TOptions> : IOptionsFactory<TOptions>
     where TOptions : class, new()
{
    private readonly IConfigureOptions<TOptions>[] _setups;
    private readonly IPostConfigureOptions<TOptions>[] _postConfigures;
    private readonly IValidateOptions<TOptions>[] _validations;

    public CultureOptionsFactory(IEnumerable<IConfigureOptions<TOptions>> setups, IEnumerable<IPostConfigureOptions<TOptions>> postConfigures, IEnumerable<IValidateOptions<TOptions>> validations)
    {
        _setups = setups as IConfigureOptions<TOptions>[] ?? setups.ToArray();
        _postConfigures = postConfigures as IPostConfigureOptions<TOptions>[] ?? postConfigures.ToArray();
        _validations = validations as IValidateOptions<TOptions>[] ?? validations.ToArray();
    }


    public TOptions Create(string name)
    {
        var defaultOptions = this.CreateOptions(Options.DefaultName, default);
        if (string.IsNullOrEmpty(name))
        {
            return defaultOptions;
        }

        var culture = CultureInfo.GetCultureInfo(name);
        var cultureStack = new Stack<CultureInfo>();

        cultureStack.Push(culture);
        while (culture.Parent.Name.AsSpan().Length > 0)
        {
            culture = culture.Parent;
            cultureStack.Push(culture);
        }

        var options = defaultOptions;
        while (cultureStack.TryPop(out var next))
        {
            options = this.CreateOptions(next.Name, options);
        }

        return options;
    }


    private TOptions CreateOptions(string name, TOptions? options)
    {
        if (options == null)
        {
            options = new TOptions();
        }

        foreach (var setup in _setups)
        {
            if (setup is IConfigureNamedOptions<TOptions> namedSetup)
            {
                namedSetup.Configure(name, options);
            }
            else if (name == Options.DefaultName)
            {
                setup.Configure(options);
            }
        }

        foreach (var post in _postConfigures)
        {
            post.PostConfigure(name, options);
        }

        if (_validations != null)
        {
            var failures = new List<string>();
            foreach (var validate in _validations)
            {
                var result = validate.Validate(name, options);
                if (result != null && result.Failed)
                {
                    failures.AddRange(result.Failures);
                }
            }
            if (failures.Count > 0)
            {
                throw new OptionsValidationException(name, typeof(TOptions), failures);
            }
        }

        return options;
    }
}

工程实现

                            -----------------
                            |               |
 JsonConfigurationSource -> | Configuration |  -> IOptionsLocalizer<TOptions>
                            |               |
                            -----------------

项目地址:
OptionsLocalization

考虑柔性负荷的综合能源系统低碳经济优化调度【考虑碳交易机制】(Matlab代码实现)内容概要:本文围绕“考虑柔性负荷的综合能源系统低碳经济优化调度”展开,重点研究在碳交易机制下如何实现综合能源系统的低碳化经济性协同优化。通过构建包含风电、光伏、储能、柔性负荷等多种能源形式的系统模型,结合碳交易成本能源调度成本,提出优化调度策略,以降低碳排放并提升系统运行经济性。文中采用Matlab进行仿真代码实现,验证了所提模型在平衡能源供需、平抑可再生能源波动、引导柔性负荷参调度等方面的有效性,为低碳能源系统的设计运行提供了技术支撑。; 适合人群:具备一定电力系统、能源系统背景,熟悉Matlab编程,从事能源优化、低碳调度、综合能源系统等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①研究碳交易机制对综合能源系统调度决策的影响;②实现柔性负荷在削峰填谷、促进可再生能源消纳中的作用;③掌握基于Matlab的能源系统建模优化求解方法;④为实际综合能源项目提供低碳经济调度方案参考。; 阅读建议:建议读者结合Matlab代码深入理解模型构建求解过程,重点关注目标函数设计、约束条件设置及碳交易成本的量化方式,可进一步扩展至多能互补、需求响应等场景进行二次开发仿真验证。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值