WPF C#:如何基于主appsettings配置加载特定站点配置文件?
解决WPF中基于主配置加载动态配置文件的问题
核心问题
你需要基于主appsettings.json中的Plant.Abbrev值加载对应appsettings.plc.{Abbrev}.json配置文件,但该值需在配置构建完成后才能获取,而默认流程中构建后无法再添加新的配置文件。以下是几种实用解决方案:
方案一:分两次构建配置(推荐)
先临时构建仅包含主配置的实例,获取Plant.Abbrev后,再构建完整的配置集合,加入所有需要的文件。逻辑清晰且符合配置系统设计,性能开销可忽略。
// 1. 临时构建配置,仅加载主appsettings.json获取站点标识 var tempConfig = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build(); string plantAbbrev = tempConfig.GetValue<string>("Plant:Abbrev"); // 2. 构建完整配置,整合所有必要文件 var configBuilder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json"); // 加入环境变量对应的配置文件(保留原有逻辑) var env = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT"); if (!string.IsNullOrEmpty(env)) { configBuilder.AddJsonFile($"appsettings.{env}.json"); } // 加入动态PLC配置文件(optional:true避免文件不存在时抛出异常) if (!string.IsNullOrEmpty(plantAbbrev)) { configBuilder.AddJsonFile($"appsettings.plc.{plantAbbrev}.json", optional: true); } var finalConfig = configBuilder.Build();
方案二:手动加载并合并配置
若不想分两次构建,可在初始配置构建完成后,手动读取动态配置文件内容,合并到现有配置实例中。需注意IConfiguration本身是只读的,需转为ConfigurationRoot操作:
var configBuilder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json"); // 加入环境配置文件(原有逻辑) var env = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT"); if (!string.IsNullOrEmpty(env)) { configBuilder.AddJsonFile($"appsettings.{env}.json"); } var config = configBuilder.Build(); string plantAbbrev = config.GetValue<string>("Plant:Abbrev"); // 读取并合并PLC配置文件 if (!string.IsNullOrEmpty(plantAbbrev)) { var plcConfigPath = Path.Combine(Directory.GetCurrentDirectory(), $"appsettings.plc.{plantAbbrev}.json"); if (File.Exists(plcConfigPath)) { var plcConfigJson = File.ReadAllText(plcConfigPath); var plcConfigDict = JsonSerializer.Deserialize<Dictionary<string, object>>(plcConfigJson); // 将配置合并到现有ConfigurationRoot if (config is ConfigurationRoot root) { var memoryProvider = new MemoryConfigurationProvider(); foreach (var kvp in plcConfigDict) { memoryProvider.Set(kvp.Key, kvp.Value); } root.Providers.Add(memoryProvider); } } }
方案三:环境变量区分开发/生产环境
针对开发环境不适用机器名的问题,可通过环境变量单独配置站点标识,生产环境仍用机器名逻辑:
- 开发环境:在
launchSettings.json中添加环境变量
"environmentVariables": { "DOTNET_ENVIRONMENT": "Development", "PLANT_ABBREV": "SAC" }
- 代码中优先读取环境变量
// 优先从环境变量拿,没有再从主配置获取 string plantAbbrev = Environment.GetEnvironmentVariable("PLANT_ABBREV") ?? tempConfig.GetValue<string>("Plant:Abbrev"); // 生产环境 fallback 到机器名逻辑 if (string.IsNullOrEmpty(plantAbbrev) && env == "Production") { plantAbbrev = Environment.MachineName.Substring(0,3); }
内容的提问来源于stack exchange,提问作者Hey Mikey
相关产品推荐
相关产品推荐

