using DeviceCommand.Base; using Logger; using Prism.Ioc; using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Reflection; using UIShare.UIViewModel; namespace UIShare.GlobalVariable { /// /// 设备管理器:根据 反射实例化所有启用的设备, /// 通过 多态统一管理,避免为每种设备单独硬编码字段。 /// public class DeviceManager { public SystemConfig _systemConfig { get; set; } /// 按 DeviceName 索引的设备字典,便于业务层按名取实例。 public IDictionary DeviceMap { get; private set; } = new Dictionary(StringComparer.OrdinalIgnoreCase); /// 类名 → Type 的反射缓存(仅扫描一次)。 private static readonly IReadOnlyDictionary _deviceTypeMap = BuildDeviceTypeMap(); public DeviceManager(SystemConfig systemConfig) { _systemConfig = systemConfig; InitDevices(); } /// /// 扫描 所在程序集中所有可实例化的实现类, /// 以类型名为键建立映射。这样新增设备类无需修改 DeviceManager。 /// private static IReadOnlyDictionary BuildDeviceTypeMap() { try { return typeof(IBaseInterface).Assembly .GetTypes() .Where(t => t.IsClass && !t.IsAbstract && typeof(IBaseInterface).IsAssignableFrom(t)) .ToDictionary(t => t.Name, t => t, StringComparer.OrdinalIgnoreCase); } catch (ReflectionTypeLoadException ex) { LoggerHelper.Error($"扫描设备类型失败:{ex.Message}"); return new Dictionary(StringComparer.OrdinalIgnoreCase); } } private void InitDevices() { DeviceMap = new Dictionary(StringComparer.OrdinalIgnoreCase); if (_systemConfig?.DeviceList == null) return; foreach (var config in _systemConfig.DeviceList) { if (config == null || !config.IsEnabled) continue; if (string.IsNullOrWhiteSpace(config.DeviceType) || !_deviceTypeMap.TryGetValue(config.DeviceType, out var deviceType)) { LoggerHelper.Warn($"未识别的设备类型 [{config.DeviceType}],已跳过 [{config.DeviceName}]。"); continue; } try { IBaseInterface? instance = config.ConnectionType switch { "Tcp" => CreateTcpDevice(deviceType, config.TcpConfig), "Serial" => CreateSerialDevice(deviceType, config.SerialPortConfig), _ => null }; if (instance == null) { LoggerHelper.Warn($"设备 [{config.DeviceName}] 连接方式 [{config.ConnectionType}] 不支持,已跳过。"); continue; } if (!string.IsNullOrWhiteSpace(config.DeviceName)) { DeviceMap[config.DeviceName] = instance; } LoggerHelper.Info($"已加载设备 [{config.DeviceName} / {config.DeviceType} / {config.ConnectionType}]"); } catch (Exception ex) { var inner = ex.InnerException?.Message ?? ex.Message; LoggerHelper.ErrorWithNotify($"设备 [{config.DeviceName}] 实例化失败:{inner}"); } } } /// /// 实例化 TCP 类设备:将 转为 POCO, /// 调用设备类的 (TcpConfig) 构造函数。 /// private static IBaseInterface? CreateTcpDevice(Type type, TcpConfigVM? vm) { vm ??= new TcpConfigVM(); var cfg = new TcpConfig { IPAddress = vm.IPAddress, Port = vm.Port, SendTimeout = vm.SendTimeout, ReceiveTimeout = vm.ReceiveTimeout }; return Activator.CreateInstance(type, cfg) as IBaseInterface; } /// /// 实例化串口类设备:将 转为 POCO, /// StopBits / Parity 从字符串解析为枚举,调用设备类的 (SerialPortConfig) 构造函数。 /// private static IBaseInterface? CreateSerialDevice(Type type, SerialPortConfigVM? vm) { vm ??= new SerialPortConfigVM(); var cfg = new SerialPortConfig { PortName = vm.PortName, BaudRate = vm.BaudRate, DataBits = vm.DataBits, StopBits = Enum.TryParse(vm.StopBits, true, out var sb) ? sb : StopBits.One, Parity = Enum.TryParse(vm.Parity, true, out var pa) ? pa : Parity.None, ReadTimeout = vm.ReadTimeout, WriteTimeout = vm.WriteTimeout }; return Activator.CreateInstance(type, cfg) as IBaseInterface; } } }