using System; using System.Configuration; using XP.Common.Logging.Interfaces; using XP.Hardware.Plc.Exceptions; namespace XP.Hardware.PLC.Configs { /// /// PLC 配置加载器(读取 App.config)| PLC Configuration Loader (reads from App.config) /// public class ConfigLoader { private readonly ILoggerService _logger; /// /// 构造函数 | Constructor /// /// 日志服务 | Logger service public ConfigLoader(ILoggerService logger) { _logger = logger.ForModule("ConfigLoader"); } /// /// 从 App.config 加载 PLC 配置 | Load PLC configuration from App.config /// /// 配置前缀,默认为 "Plc" | Configuration prefix, default is "Plc" /// PLC 配置对象 | PLC configuration object public PlcConfig LoadPlcConfig(string prefix = "Plc") { try { _logger.Info($"开始从 App.config 加载 PLC 配置,前缀: {prefix}"); var config = new PlcConfig(); // 读取 IP 地址 | Read IP address var ipAddress = ConfigurationManager.AppSettings[$"{prefix}:IpAddress"]; if (!string.IsNullOrEmpty(ipAddress)) { config.IpAddress = ipAddress; } // 读取端口号 | Read port var port = ConfigurationManager.AppSettings[$"{prefix}:Port"]; if (int.TryParse(port, out var portValue)) { config.Port = portValue; } // 读取 Rack | Read Rack var rack = ConfigurationManager.AppSettings[$"{prefix}:Rack"]; if (short.TryParse(rack, out var rackValue)) { config.Rack = rackValue; } // 读取 Slot | Read Slot var slot = ConfigurationManager.AppSettings[$"{prefix}:Slot"]; if (short.TryParse(slot, out var slotValue)) { config.Slot = slotValue; } // 读取 PLC 类型 | Read PLC type var plcType = ConfigurationManager.AppSettings[$"{prefix}:PlcType"]; if (!string.IsNullOrEmpty(plcType) && Enum.TryParse(plcType, true, out var plcTypeValue)) { config.PlcType = plcTypeValue; } else if (!string.IsNullOrEmpty(plcType)) { _logger.Warn($"无效的 PLC 类型: {plcType},使用默认值: {config.PlcType}"); } // 读取数据块配置 | Read data block configuration var readDbBlock = ConfigurationManager.AppSettings[$"{prefix}:ReadDbBlock"]; if (!string.IsNullOrEmpty(readDbBlock)) { config.ReadDbBlock = readDbBlock; } var readStartAddress = ConfigurationManager.AppSettings[$"{prefix}:ReadStartAddress"]; if (int.TryParse(readStartAddress, out var readStartValue)) { config.ReadStartAddress = readStartValue; } var readLength = ConfigurationManager.AppSettings[$"{prefix}:ReadLength"]; if (int.TryParse(readLength, out var readLengthValue)) { config.ReadLength = readLengthValue; } // 读取批量读取周期 | Read bulk read interval var bulkReadInterval = ConfigurationManager.AppSettings[$"{prefix}:BulkReadIntervalMs"]; if (int.TryParse(bulkReadInterval, out var bulkReadIntervalValue)) { config.BulkReadIntervalMs = bulkReadIntervalValue; } // 读取超时配置 | Read timeout configuration var connectTimeout = ConfigurationManager.AppSettings[$"{prefix}:ConnectTimeoutMs"]; if (int.TryParse(connectTimeout, out var connectTimeoutValue)) { config.ConnectTimeoutMs = connectTimeoutValue; } var readTimeout = ConfigurationManager.AppSettings[$"{prefix}:ReadTimeoutMs"]; if (int.TryParse(readTimeout, out var readTimeoutValue)) { config.ReadTimeoutMs = readTimeoutValue; } var writeTimeout = ConfigurationManager.AppSettings[$"{prefix}:WriteTimeoutMs"]; if (int.TryParse(writeTimeout, out var writeTimeoutValue)) { config.WriteTimeoutMs = writeTimeoutValue; } // 读取重连配置 | Read reconnection configuration var bReConnect = ConfigurationManager.AppSettings[$"{prefix}:bReConnect"]; if (bool.TryParse(bReConnect, out var bReConnectValue)) { config.bReConnect = bReConnectValue; } // 验证配置参数 | Validate configuration parameters ValidateConfig(config); _logger.Info($"成功加载 PLC 配置: {config.IpAddress}:{config.Port}, Rack={config.Rack}, Slot={config.Slot}, 型号={config.PlcType}"); return config; } catch (PlcException) { // PlcException 直接向上抛出 | Re-throw PlcException throw; } catch (Exception ex) { _logger.Error(ex, $"加载 PLC 配置失败: {ex.Message}"); throw new PlcException("配置加载失败", ex); } } /// /// 验证配置参数 | Validate configuration parameters /// /// PLC 配置对象 | PLC configuration object private void ValidateConfig(PlcConfig config) { // 验证 IP 地址不为空 | Validate IP address is not empty if (string.IsNullOrWhiteSpace(config.IpAddress)) { throw new PlcException("PLC IP 地址不能为空"); } // 验证端口号范围 (1-65535) | Validate port range (1-65535) if (config.Port < 1 || config.Port > 65535) { throw new PlcException($"PLC 端口号无效: {config.Port},有效范围: 1-65535"); } // 验证 Rack 范围 (0-7) | Validate Rack range (0-7) if (config.Rack < 0 || config.Rack > 7) { throw new PlcException($"Rack 参数无效: {config.Rack},有效范围: 0-7"); } // 验证 Slot 范围 (0-31) | Validate Slot range (0-31) if (config.Slot < 0 || config.Slot > 31) { throw new PlcException($"Slot 参数无效: {config.Slot},有效范围: 0-31"); } // 验证超时时间大于 0 | Validate timeout is greater than 0 if (config.ConnectTimeoutMs <= 0) { throw new PlcException($"连接超时时间无效: {config.ConnectTimeoutMs},必须大于 0"); } if (config.ReadTimeoutMs <= 0) { throw new PlcException($"读取超时时间无效: {config.ReadTimeoutMs},必须大于 0"); } if (config.WriteTimeoutMs <= 0) { throw new PlcException($"写入超时时间无效: {config.WriteTimeoutMs},必须大于 0"); } // 验证数据块配置,缺失时使用默认值 | Validate data block configuration, use default if missing if (string.IsNullOrWhiteSpace(config.ReadDbBlock)) { _logger.Warn("ReadDbBlock 未配置,使用默认值: DB1"); config.ReadDbBlock = "DB1"; } if (config.ReadLength <= 0) { _logger.Warn($"ReadLength 无效: {config.ReadLength},使用默认值: 100"); config.ReadLength = 100; } if (config.ReadStartAddress < 0) { _logger.Warn($"ReadStartAddress 无效: {config.ReadStartAddress},使用默认值: 0"); config.ReadStartAddress = 0; } // 验证批量读取周期 | Validate bulk read interval if (config.BulkReadIntervalMs <= 0) { _logger.Warn($"BulkReadIntervalMs 无效: {config.BulkReadIntervalMs},使用默认值: 100"); config.BulkReadIntervalMs = 100; } } } }