如何高效创建C# Model类?优化多国家配置映射方案
优化移动端配置模型与映射方案
问题背景
当前配置采用扁平化键值对格式(如Mobile:techUK),模型类通过重复定义带国家后缀的属性实现绑定,导致代码冗余、维护成本高。
现有配置数据
{ "Mobile:techUK": "977455454545", "Mobile:saleUK": "977455454545", "Mobile:supportUK": "977455454545", "Mobile:techCH": "977455454545", "Mobile:saleCH": "977455454545", "Mobile:supportCH": "977455454545", "Mobile:techUS": "977455454545", "Mobile:saleUS": "977455454545", "Mobile:supporUS": "977455454545" }
现有模型代码
public class MobileConfig: IMobileConfig { public class Info { public string? techUK { get; set; } public string? saleUK { get; set; } public string? supportUK { get; set; } public string? techCH { get; set; } public string? saleCH { get; set; } public string? supportCH { get; set; } public string? techUS { get; set; } public string? saleUS { get; set; } public string? supporUS { get; set; } } }
现有依赖注入配置
services.Configure<MobileConfig.Info>(_configuration.GetSection("Mobile")); services.AddTransient<IMobileConfig, MobileConfig>(s => new MobileConfig(s.GetService<IOptionsSnapshot<MobileConfig.Info>>()));
优化方案
方案1:不修改现有配置,通过解析键实现分组
适用于无法调整现有配置结构的场景,核心是在模型构造函数中解析扁平化的键,将数据按国家和类别分组。
步骤1:重构模型类
定义CountryMobileSettings封装单国家的三类联系方式,再通过字典实现多国家的配置存储:
// 单国家的移动端配置 public class CountryMobileSettings { public string? Tech { get; set; } public string? Sale { get; set; } public string? Support { get; set; } } // 重构后的MobileConfig public class MobileConfig : IMobileConfig { // 键为国家代码(如UK、CH、US),值为对应国家的配置 public Dictionary<string, CountryMobileSettings> CountrySettings { get; } public MobileConfig(IOptionsSnapshot<IConfigurationSection> mobileConfigSection) { CountrySettings = new Dictionary<string, CountryMobileSettings>(StringComparer.OrdinalIgnoreCase); var allSettings = mobileConfigSection.Value.GetChildren(); foreach (var setting in allSettings) { var keyParts = SplitKey(setting.Key); if (keyParts == null) continue; var (category, country) = keyParts; if (!CountrySettings.TryGetValue(country, out var countrySettings)) { countrySettings = new CountryMobileSettings(); CountrySettings[country] = countrySettings; } // 根据类别赋值 switch (category.ToLowerInvariant()) { case "tech": countrySettings.Tech = setting.Value; break; case "sale": countrySettings.Sale = setting.Value; break; case "support": countrySettings.Support = setting.Value; break; } } } // 拆分键名:例如将"techUK"拆分为类别"tech"和国家"UK" private (string Category, string Country)? SplitKey(string key) { // 找到最后一个大写字母的位置(假设国家代码为大写后缀) var splitIndex = key.LastIndexOfAny("ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray()); if (splitIndex <= 0) return null; var category = key.Substring(0, splitIndex); var country = key.Substring(splitIndex); return (category, country); } }
步骤2:调整依赖注入配置
直接注入Mobile配置节,而非绑定到原有的Info类:
// 注册配置节 services.AddOptions(); services.AddTransient<IOptionsSnapshot<IConfigurationSection>>(s => Options.Create(s.GetRequiredService<IConfiguration>().GetSection("Mobile"))); // 注册重构后的MobileConfig services.AddTransient<IMobileConfig, MobileConfig>();
方案2:调整配置结构为嵌套格式,利用原生绑定
如果允许修改配置文件,将配置改为嵌套结构可以直接使用.NET的配置绑定功能,代码更简洁。
步骤1:修改配置结构
{ "Mobile": { "UK": { "tech": "977455454545", "sale": "977455454545", "support": "977455454545" }, "CH": { "tech": "977455454545", "sale": "977455454545", "support": "977455454545" }, "US": { "tech": "977455454545", "sale": "977455454545", "support": "977455454545" } } }
步骤2:重构模型类
public class CountryMobileSettings { public string? Tech { get; set; } public string? Sale { get; set; } public string? Support { get; set; } } public class MobileConfig : IMobileConfig { public Dictionary<string, CountryMobileSettings> CountrySettings { get; set; } = new(); }
步骤3:调整依赖注入配置
直接使用原生配置绑定:
services.Configure<MobileConfig>(_configuration.GetSection("Mobile")); services.AddTransient<IMobileConfig, MobileConfig>(s => s.GetRequiredService<IOptionsSnapshot<MobileConfig>>().Value);
使用示例
无论采用哪种方案,后续使用时都可以通过国家代码快速获取对应配置:
public class SomeService { private readonly IMobileConfig _mobileConfig; public SomeService(IMobileConfig mobileConfig) { _mobileConfig = mobileConfig; } public void UseUKTechNumber() { var ukTechNumber = _mobileConfig.CountrySettings["UK"].Tech; // 业务逻辑处理 } }
内容的提问来源于stack exchange,提问作者june alex
相关产品推荐
相关产品推荐

