From e57938fbda9bff702004038f76d009422968bff5 Mon Sep 17 00:00:00 2001
From: alielie <alielie@git.com>
Date: 星期五, 06 十一月 2026 18:05:07 +0800
Subject: [PATCH] 提交代码

---
 DeviceService/DeviceManager/DeviceHelper.cs |  168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 168 insertions(+), 0 deletions(-)

diff --git a/DeviceService/DeviceManager/DeviceHelper.cs b/DeviceService/DeviceManager/DeviceHelper.cs
new file mode 100644
index 0000000..3a11021
--- /dev/null
+++ b/DeviceService/DeviceManager/DeviceHelper.cs
@@ -0,0 +1,168 @@
+using DeviceService.Core;
+using DeviceService.Logging;
+using System.Reflection;
+
+namespace DeviceService.Device
+{
+    /// <summary>
+    /// 璁惧淇℃伅鎸佷箙鍖栬緟鍔╋細璐熻矗璁惧淇℃伅涓� Config\Devices.db 涔嬮棿鐨勮鍐欍��
+    /// DeviceManager 鍙礋璐f湇鍔℃寮忓惎鍔ㄥ悗鐨勮澶囩鐞嗭紝鏁版嵁搴撹鍐欎竴寰嬬粡鐢辨湰绫汇��
+    /// </summary>
+    public static class DeviceHelper
+    {
+
+        private static readonly object _scanSync = new object();
+        private static readonly Dictionary<string, Type> _deviceTypeMap = new Dictionary<string, Type>(StringComparer.Ordinal);
+
+        /// <summary>
+        /// 鎵弿鍒扮殑璁惧绫诲瀷鍒楄〃锛堝彇鑷� DeviceDescAttribute.Type锛夈��
+        /// 绋嬪簭鍚姩鍚庤皟鐢� <see cref="ScanDeviceTypes"/> 濉厖銆�
+        /// </summary>
+        public static List<string> AllDeviceType { get; } = new List<string>();
+        public static List<IDevice> AllDevices { get; } = new List<IDevice>();
+
+        /// <summary>
+        /// 鎵弿鏈▼搴忛泦涓墍鏈夋爣娉ㄤ簡 <see cref="DeviceDescAttribute"/> 涓旂户鎵� <see cref="IDevice"/> 鐨勭被锛�
+        /// 灏嗘敞瑙d腑鐨� Type 瀛樺叆 <see cref="AllDeviceType"/>锛屽苟璁板綍 Type 鍒拌澶囩被鐨勬槧灏勩��
+        /// </summary>
+        public static void ScanDeviceTypes()
+        {
+            lock (_scanSync)
+            {
+                AllDeviceType.Clear();
+                _deviceTypeMap.Clear();
+
+                IEnumerable<Type?> types;
+                try
+                {
+                    types = Assembly.GetExecutingAssembly().GetTypes();
+                }
+                catch (ReflectionTypeLoadException ex)
+                {
+                    types = ex.Types;
+                }
+
+                foreach (Type? t in types)
+                {
+                    if (t == null || !typeof(IDevice).IsAssignableFrom(t) || t.IsAbstract)
+                    {
+                        continue;
+                    }
+
+                    DeviceDescAttribute? attr = t.GetCustomAttribute<DeviceDescAttribute>(false);
+                    if (attr == null || string.IsNullOrEmpty(attr.Type))
+                    {
+                        continue;
+                    }
+
+                    _deviceTypeMap[attr.Type] = t;
+                    AllDeviceType.Add(attr.Type);
+                }
+            }
+        }
+
+        /// <summary>鎸夋敞瑙� Type 鍒涘缓瀵瑰簲鐨勮澶囧疄渚嬨��</summary>
+        public static bool TryCreateDevice(string type, out IDevice? device)
+        {
+            device = null;
+            lock (_scanSync)
+            {
+                if (type == null || !_deviceTypeMap.TryGetValue(type, out Type? deviceType))
+                {
+                    return false;
+                }
+
+                device = (IDevice?)Activator.CreateInstance(deviceType);
+                return device != null;
+            }
+        }
+
+        /// <summary>
+        /// 淇濆瓨璁惧淇℃伅鍒� Config\Devices.db锛堜粎鎸佷箙鍖栵紝涓嶈皟鐢� Init銆佷笉褰卞搷 DeviceManager 鐨勫唴瀛橀泦鍚堬級銆�
+        /// 杩斿洖鏄惁淇濆瓨鎴愬姛锛涙柊澧炶褰曚細鍥炲~鑷 Id銆�
+        /// </summary>
+        public static bool SaveDevice(IDevice device)
+        {
+            if (device == null) throw new ArgumentNullException(nameof(device));
+
+            // 鍐欏叆 Config\Devices.db锛屼笅娆″惎鍔ㄦ椂鎹鎭㈠璁惧鍒楄〃锛涙柊澧炶褰曞洖濉嚜澧� Id
+            long id = DeviceDatabase.Instance.Save(ToRecord(device));
+            if (id > 0)
+            {
+                TrySet(device, nameof(IDevice.Id), id);
+            }
+
+            return id > 0;
+        }
+
+        /// <summary>
+        /// 浠� Config\Devices.db 璇诲彇鍏ㄩ儴璁惧骞跺垱寤哄疄渚嬶紙涓嶈皟鐢� Init銆佷笉鍔犲叆浠讳綍闆嗗悎锛夈��
+        /// 璋冪敤鏂规寜闇�鍔犲叆 DeviceManager锛屾湇鍔℃寮忓惎鍔ㄥ悗鍐嶉�愪竴 <see cref="DeviceManager.Register"/>銆�
+        /// </summary>
+        public static IReadOnlyList<IDevice> LoadDevices()
+        {
+            var devices = new List<IDevice>();
+            AllDevices.Clear();
+
+            foreach (DeviceRecord record in DeviceDatabase.Instance.LoadAll())
+            {
+                if (string.IsNullOrWhiteSpace(record.DeviceId) || string.IsNullOrWhiteSpace(record.Type))
+                {
+                    continue;
+                }
+
+                if (!DeviceHelper.TryCreateDevice(record.Type, out IDevice? device) || device == null)
+                {
+                    GlobalLogger.Logger.Warn("DeviceHelper", $"[璁惧搴揮 鏈煡璁惧绫诲瀷 {record.Type}锛屽凡璺宠繃 {record.DeviceId}");
+                    continue;
+                }
+
+                ApplyRecord(device, record);
+                devices.Add(device);
+                AllDevices.Add(device);
+            }
+
+            return devices;
+        }
+
+        /// <summary>浠� Config\Devices.db 鍒犻櫎璁惧璁板綍銆�</summary>
+        public static void RemoveDevice(string deviceId)
+        {
+            DeviceDatabase.Instance.Remove(deviceId);
+        }
+
+        private static DeviceRecord ToRecord(IDevice device)
+        {
+            return new DeviceRecord
+            {
+                Id = device.Id,
+                DeviceId = device.DeviceId ?? string.Empty,
+                Type = device.Type ?? string.Empty,
+                Brand = device.Brand ?? string.Empty,
+                ConnectStr = device.ConnectStr ?? string.Empty,
+                AccessType = device.AccessType
+            };
+        }
+
+        /// <summary>IDevice 鎺ュ彛鍙毚闇� getter锛屽疄鐜扮被涓�鑸湁 setter锛岄�氳繃鍙嶅皠鍥炲~銆�</summary>
+        private static void ApplyRecord(IDevice device, DeviceRecord record)
+        {
+            TrySet(device, nameof(IDevice.Id), record.Id);
+            TrySet(device, nameof(IDevice.DeviceId), record.DeviceId);
+            TrySet(device, nameof(IDevice.Brand), record.Brand);
+            TrySet(device, nameof(IDevice.ConnectStr), record.ConnectStr);
+            TrySet(device, nameof(IDevice.AccessType), record.AccessType);
+        }
+
+        private static void TrySet(object target, string propertyName, object value)
+        {
+            PropertyInfo? property = target.GetType().GetProperty(propertyName);
+            if (property == null || !property.CanWrite || !property.PropertyType.IsInstanceOfType(value))
+            {
+                return;
+            }
+
+            property.SetValue(target, value);
+        }
+    }
+}

--
Gitblit v1.9.1