VisualizationProcessorFactory.cs 5.46 KB
using System.Collections.Concurrent;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Rcs.Domain.Attributes;

namespace Rcs.Infrastructure.Mqtt.ProcessorFactory;

/// <summary>
/// 可视化数据处理器工厂实现 - 通过反射自动发现并注册处理器
/// 扫描 Infrastructure 程序集中实现 IVisualizationDataProcessor 且带有
/// [ProtocolInfo(*, *, "VisualizationProcessor")] 标记的类,按制造商注册
/// @author zzy
/// </summary>
public class VisualizationProcessorFactory : IVisualizationProcessorFactory
{
    private readonly ILogger<VisualizationProcessorFactory> _logger;
    private readonly IServiceProvider _serviceProvider;
    private readonly ConcurrentDictionary<string, IVisualizationDataProcessor> _processors;

    /// <summary>
    /// 处理器工厂Topic标识,用于 [ProtocolInfo] 属性的 Topic 字段匹配
    /// </summary>
    private const string ProcessorTopic = "VisualizationProcessor";

    public VisualizationProcessorFactory(
        ILogger<VisualizationProcessorFactory> logger,
        IServiceProvider serviceProvider)
    {
        _logger = logger;
        _serviceProvider = serviceProvider;
        _processors = new ConcurrentDictionary<string, IVisualizationDataProcessor>(StringComparer.OrdinalIgnoreCase);
        RegisterDefaultProcessors();
    }

    /// <summary>
    /// 获取指定制造商的处理器,未找到时回退到默认处理器
    /// @author zzy
    /// </summary>
    public IVisualizationDataProcessor GetProcessor(string manufacturer)
    {
        if (!string.IsNullOrWhiteSpace(manufacturer) && _processors.TryGetValue(manufacturer, out var processor))
        {
            return processor;
        }

        // 回退到默认处理器
        if (_processors.TryGetValue("Default", out var defaultProcessor))
        {
            _logger.LogDebug("未找到制造商 '{Manufacturer}' 的专用处理器,使用默认处理器", manufacturer);
            return defaultProcessor;
        }

        // 极端情况:连默认处理器都没有,不应发生
        _logger.LogWarning("未找到任何可视化处理器,制造商: '{Manufacturer}'", manufacturer);
        throw new InvalidOperationException($"未找到制造商 '{manufacturer}' 的可视化处理器,且默认处理器未注册");
    }

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

    /// <summary>
    /// 手动刷新并重新注册处理器
    /// @author zzy
    /// </summary>
    public void RefreshProcessors()
    {
        _logger.LogInformation("开始手动刷新可视化数据处理器");
        _processors.Clear();
        RegisterDefaultProcessors();
    }

    /// <summary>
    /// 获取已注册处理器的详细信息
    /// @author zzy
    /// </summary>
    public Dictionary<string, string> GetRegisteredProcessorsInfo()
    {
        return _processors.ToDictionary(
            kvp => kvp.Key,
            kvp => kvp.Value.GetType().Name,
            StringComparer.OrdinalIgnoreCase);
    }

    /// <summary>
    /// 反射扫描 Infrastructure 程序集,自动发现并注册处理器
    /// 查找实现 IVisualizationDataProcessor 且带有 [ProtocolInfo(*, *, "VisualizationProcessor")] 的类
    /// @author zzy
    /// </summary>
    private void RegisterDefaultProcessors()
    {
        try
        {
            var assembly = Assembly.GetExecutingAssembly();
            var processorTypes = assembly.GetTypes()
                .Where(type => type.IsClass && !type.IsAbstract)
                .Where(type => typeof(IVisualizationDataProcessor).IsAssignableFrom(type))
                .Where(type =>
                {
                    var protocolInfo = type.GetCustomAttribute<ProtocolInfoAttribute>();
                    return protocolInfo != null &&
                           string.Equals(protocolInfo.Topic, ProcessorTopic, StringComparison.OrdinalIgnoreCase);
                })
                .ToList();

            foreach (var type in processorTypes)
            {
                var protocolInfo = type.GetCustomAttribute<ProtocolInfoAttribute>()!;
                try
                {
                    // 通过 DI 容器实例化处理器,自动注入构造函数依赖
                    var instance = (IVisualizationDataProcessor)ActivatorUtilities.CreateInstance(_serviceProvider, type);
                    _processors.AddOrUpdate(protocolInfo.Manufacturer, instance, (_, _) => instance);
                    _logger.LogInformation(
                        "注册可视化数据处理器: Manufacturer={Manufacturer}, Type={TypeName}",
                        protocolInfo.Manufacturer, type.Name);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex,
                        "实例化可视化数据处理器失败: Manufacturer={Manufacturer}, Type={TypeName}",
                        protocolInfo.Manufacturer, type.Name);
                }
            }

            _logger.LogInformation("可视化数据处理器注册完成,共注册 {Count} 个处理器: [{Manufacturers}]",
                _processors.Count, string.Join(", ", _processors.Keys));
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "自动注册可视化数据处理器时发生异常");
        }
    }
}