StateParserFactory.cs 7.73 KB
using System.Collections.Concurrent;
using System.Reflection;
using System.Text.Json;
using Microsoft.Extensions.Logging;
using Rcs.Domain.Extensions;
using Rcs.Domain.Models.VDA5050;

namespace Rcs.Infrastructure.Mqtt.ParseFactory
{
    /// <summary>
    /// 状态解析器工厂实现
    /// </summary>
    public class StateParserFactory : IStateParserFactory
    {
        private readonly ILogger<StateParserFactory> _logger;
        private readonly ConcurrentDictionary<string, Func<string, State?>> _parsers;

        public StateParserFactory(ILogger<StateParserFactory> logger)
        {
            _logger = logger;
            _parsers = new ConcurrentDictionary<string, Func<string, State?>>(StringComparer.OrdinalIgnoreCase);
            
            // 注册默认支持的制造商解析器
            RegisterDefaultParsers();
        }

        /// <summary>
        /// 按制造商名称解析状态信息
        /// </summary>
        public State? ParseState(string manufacturer, string payload)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(manufacturer))
                {
                    _logger.LogWarning("制造商为空,使用默认VDA5050状态解析器");
                    return ParseDefaultState(payload);
                }

                if (_parsers.TryGetValue(manufacturer, out var parser))
                {
                    return parser(payload);
                }
                else
                {
                    _logger.LogInformation("未找到制造商 '{Manufacturer}' 的专用解析器,使用默认VDA5050解析器", manufacturer);
                    return ParseDefaultState(payload);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "解析制造商 '{Manufacturer}' 的状态信息时发生异常", manufacturer);
                return null;
            }
        }

        /// <summary>
        /// 注册指定制造商的状态解析器
        /// </summary>
        public void RegisterStateParser(string manufacturer, Func<string, State?> parser)
        {
            if (string.IsNullOrWhiteSpace(manufacturer))
            {
                throw new ArgumentException("制造商名不能为空", nameof(manufacturer));
            }

            if (parser == null)
            {
                throw new ArgumentNullException(nameof(parser));
            }

            _parsers.AddOrUpdate(manufacturer, parser, (key, oldValue) => parser);
        }

        /// <summary>
        /// 是否支持指定制造商
        /// </summary>
        public bool IsManufacturerSupported(string manufacturer)
        {
            return !string.IsNullOrWhiteSpace(manufacturer) && _parsers.ContainsKey(manufacturer);
        }

        /// <summary>
        /// 获取所有已注册的制造商
        /// </summary>
        public IEnumerable<string> GetSupportedManufacturers()
        {
            return _parsers.Keys.ToList();
        }

        /// <summary>
        /// 注册默认解析器 - 自动扫描带有ProtocolInfo属性的State类
        /// </summary>
        private void RegisterDefaultParsers()
        {
            try
            {
                // 获取HaHRCS.Core程序集
                var coreAssembly = Assembly.GetAssembly(typeof(State));
                if (coreAssembly == null)
                {
                    _logger.LogWarning("无法获取HaHRCS.Core.Models.VDA5050程序集");
                    return;
                }

                // 扫描所有带有ProtocolInfo且Topic为"State"的类
                var stateTypes = coreAssembly.GetTypes()
                    .Where(type => type.IsClass && !type.IsAbstract)
                    //.Where(type => typeof(State).IsAssignableFrom(type))
                    .Where(type => 
                    {
                        var protocolInfo = type.GetCustomAttribute<ProtocolInfoAttribute>();
                        return protocolInfo != null && 
                               string.Equals(protocolInfo.Topic, nameof(State), StringComparison.OrdinalIgnoreCase);
                    })
                    .ToList();

                foreach (var stateType in stateTypes)
                {
                    var protocolInfo = stateType.GetCustomAttribute<ProtocolInfoAttribute>();
                    if (protocolInfo != null)
                    {
                        // 注册解析器
                        var parser = CreateParserForType(stateType);

                        RegisterStateParser(protocolInfo.Manufacturer, parser);
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "自动注册默认解析器时发生异常");
            }
        }

        /// <summary>
        /// 为指定类型创建解析器委托
        /// </summary>
        /// <param name="stateType">State类型</param>
        /// <returns>解析器委托</returns>
        private Func<string, State?> CreateParserForType(Type stateType)
        {
            return payload =>
            {
                try
                {
                    var result = JsonSerializer.Deserialize(payload, stateType);
                    return result as State;
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, "解析 {StateType} 类型时发生错误", stateType.Name);
                    return null;
                }
            };
        }

        /// <summary>
        /// 解析默认VDA5050状态信息
        /// </summary>
        private static State? ParseDefaultState(string payload)
        {
            try
            {
                return JsonSerializer.Deserialize<State>(payload);
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 手动刷新并重新注册解析器
        /// </summary>
        public void RefreshParsers()
        {
            _logger.LogInformation("开始手动刷新解析器");
            _parsers.Clear();
            RegisterDefaultParsers();
        }

        /// <summary>
        /// 自动根据程序集扫描ProtocolInfo属性获取已注册解析器的详细信息
        /// </summary>
        public Dictionary<string, string> GetRegisteredParsersInfo()
        {
            var result = new Dictionary<string, string>();
            
            try
            {
                var coreAssembly = Assembly.GetAssembly(typeof(State));
                if (coreAssembly != null)
                {
                    var stateTypes = coreAssembly.GetTypes()
                        .Where(type => type.IsClass && !type.IsAbstract)
                        .Where(type => typeof(State).IsAssignableFrom(type))
                        .Where(type => 
                        {
                            var protocolInfo = type.GetCustomAttribute<ProtocolInfoAttribute>();
                            return protocolInfo != null &&
                                   protocolInfo.Topic.Equals(nameof(State), StringComparison.OrdinalIgnoreCase);
                        });

                    foreach (var stateType in stateTypes)
                    {
                        var protocolInfo = stateType.GetCustomAttribute<ProtocolInfoAttribute>();
                        if (protocolInfo != null)
                        {
                            result[protocolInfo.Manufacturer] = $"{stateType.Name} (v{protocolInfo.Version})";
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取解析器信息时发生异常");
            }

            return result;
        }
    }
}