插件式架构:解耦与扩展的艺术与实践(超详细)

插件式架构:解耦与扩展的艺术与实践

🤔 什么是插件式开发?

插件式开发(Plugin-based Development)是一种软件架构模式,它允许应用程序在运行时动态加载、卸载和执行扩展功能模块,而无需修改主程序的核心代码。这种架构将应用程序的核心功能与可扩展功能分离,通过定义良好的接口契约实现模块间的松耦合。

插件式开发的核心概念

插件(Plugin):一个独立的、可替换的软件模块,实现了特定的接口契约,用于扩展宿主应用程序的功能。

宿主程序(Host):包含核心功能的主应用程序,负责发现、加载、管理和执行插件。

契约(Contract):插件与宿主程序之间交互的接口定义,确保双方能够正确通信。

插件式架构的历史演变

插件式架构并非新鲜概念,其思想可以追溯到几十年前的操作系统设计。现代插件系统的典型代表包括:

  1. Eclipse IDE - 完全基于插件的开发环境
  2. Visual Studio Code - 通过扩展机制提供丰富功能
  3. Photoshop - 支持滤镜、脚本等插件扩展
  4. Web浏览器 - 通过插件/扩展增强功能
  5. 游戏引擎 - 如Unity、Unreal Engine的插件系统

现代插件系统的特征

  • 动态性:插件可以在运行时加载和卸载
  • 隔离性:插件错误不应导致宿主程序崩溃
  • 版本兼容性:支持不同版本插件的共存
  • 安全性:插件应运行在受限环境中,防止恶意行为
  • 发现机制:宿主程序能够自动发现可用插件

🧩 为何选择插件式开发?------ 解耦与扩展的艺术

1. 高度解耦:模块化设计的极致体现

代码耦合度分析:

csharp 复制代码
// 紧耦合的代码示例 - 不推荐
public class ReportGenerator
{
    private PdfExporter _pdfExporter = new PdfExporter();
    private ExcelExporter _excelExporter = new ExcelExporter();
    
    public void GenerateReport(string format, Data data)
    {
        if (format == "PDF")
            _pdfExporter.Export(data);
        else if (format == "Excel")
            _excelExporter.Export(data);
        // 每添加一个新格式,都需要修改这个类
    }
}

// 使用插件架构的解耦实现
public interface IExportPlugin
{
    string Format { get; }
    void Export(Data data);
}

public class ReportGenerator
{
    private List<IExportPlugin> _plugins = new List<IExportPlugin>();
    
    public void RegisterPlugin(IExportPlugin plugin)
    {
        _plugins.Add(plugin);
    }
    
    public void GenerateReport(string format, Data data)
    {
        var plugin = _plugins.FirstOrDefault(p => p.Format == format);
        plugin?.Export(data);
    }
}

解耦带来的好处:

  • 独立开发:不同团队可以并行开发不同插件
  • 独立测试:每个插件可以单独进行单元测试
  • 独立部署:插件可以单独更新,不影响主程序
  • 技术异构:不同插件可以使用不同的技术栈

2. 极致的扩展性:应对需求变化的利器

扩展性设计模式:

csharp 复制代码
// 策略模式在插件系统中的应用
public interface ISortStrategy
{
    void Sort(List<int> data);
}

public class QuickSortPlugin : ISortStrategy
{
    public void Sort(List<int> data)
    {
        // 快速排序实现
        QuickSort(data, 0, data.Count - 1);
    }
    
    private void QuickSort(List<int> arr, int low, int high)
    {
        if (low < high)
        {
            int pi = Partition(arr, low, high);
            QuickSort(arr, low, pi - 1);
            QuickSort(arr, pi + 1, high);
        }
    }
    
    private int Partition(List<int> arr, int low, int high)
    {
        int pivot = arr[high];
        int i = low - 1;
        
        for (int j = low; j < high; j++)
        {
            if (arr[j] < pivot)
            {
                i++;
                (arr[i], arr[j]) = (arr[j], arr[i]);
            }
        }
        (arr[i + 1], arr[high]) = (arr[high], arr[i + 1]);
        return i + 1;
    }
}

public class MergeSortPlugin : ISortStrategy
{
    public void Sort(List<int> data)
    {
        // 归并排序实现
        if (data.Count <= 1) return;
        
        int mid = data.Count / 2;
        List<int> left = data.GetRange(0, mid);
        List<int> right = data.GetRange(mid, data.Count - mid);
        
        Sort(left);
        Sort(right);
        Merge(data, left, right);
    }
    
    private void Merge(List<int> result, List<int> left, List<int> right)
    {
        int i = 0, j = 0, k = 0;
        
        while (i < left.Count && j < right.Count)
        {
            if (left[i] <= right[j])
                result[k++] = left[i++];
            else
                result[k++] = right[j++];
        }
        
        while (i < left.Count) result[k++] = left[i++];
        while (j < right.Count) result[k++] = right[j++];
    }
}

3. 增强可维护性:长期项目的守护者

维护性指标:

  • 圈复杂度降低:每个插件专注于单一职责
  • 代码重复减少:通用功能可以提取为共享插件
  • 变更影响分析简化:修改插件只影响局部功能
  • 技术债务管理:可以逐步替换老旧的插件

版本管理示例:

csharp 复制代码
// 插件版本管理
[AttributeUsage(AttributeTargets.Class)]
public class PluginMetadataAttribute : Attribute
{
    public string Name { get; }
    public Version Version { get; }
    public string Author { get; }
    public string Description { get; }
    
    public PluginMetadataAttribute(string name, string version, 
                                  string author = "", string description = "")
    {
        Name = name;
        Version = new Version(version);
        Author = author;
        Description = description;
    }
}

// 插件接口支持版本
public interface IPlugin
{
    Version ApiVersion { get; }
    string Name { get; }
    
    void Initialize();
    void Execute();
    void Cleanup();
}

// 使用版本控制的插件加载器
public class VersionAwarePluginLoader
{
    private readonly Dictionary<Version, List<IPlugin>> _pluginsByVersion 
        = new Dictionary<Version, List<IPlugin>>();
    
    public void LoadPlugin(IPlugin plugin)
    {
        if (!_pluginsByVersion.ContainsKey(plugin.ApiVersion))
            _pluginsByVersion[plugin.ApiVersion] = new List<IPlugin>();
        
        _pluginsByVersion[plugin.ApiVersion].Add(plugin);
        plugin.Initialize();
    }
    
    public void ExecutePlugins(Version minVersion)
    {
        var compatiblePlugins = _pluginsByVersion
            .Where(kv => kv.Key >= minVersion)
            .SelectMany(kv => kv.Value);
        
        foreach (var plugin in compatiblePlugins)
        {
            try
            {
                plugin.Execute();
            }
            catch (Exception ex)
            {
                // 优雅处理插件异常
                LogError($"Plugin {plugin.Name} failed: {ex.Message}");
            }
        }
    }
}

4. 支持动态加载与卸载:灵活性的终极体现

动态生命周期管理:

csharp 复制代码
// 支持热插拔的插件管理器
public class HotSwapPluginManager : IDisposable
{
    private readonly string _pluginsDirectory;
    private readonly Dictionary<string, PluginContext> _loadedPlugins;
    private FileSystemWatcher _fileWatcher;
    
    public HotSwapPluginManager(string pluginsDirectory)
    {
        _pluginsDirectory = pluginsDirectory;
        _loadedPlugins = new Dictionary<string, PluginContext>();
        
        // 监视插件目录变化
        _fileWatcher = new FileSystemWatcher(pluginsDirectory, "*.dll")
        {
            EnableRaisingEvents = true,
            IncludeSubdirectories = false
        };
        
        _fileWatcher.Created += OnPluginFileCreated;
        _fileWatcher.Deleted += OnPluginFileDeleted;
        _fileWatcher.Changed += OnPluginFileChanged;
    }
    
    private class PluginContext
    {
        public Assembly Assembly { get; set; }
        public IPlugin PluginInstance { get; set; }
        public DateTime LastLoadTime { get; set; }
        public AppDomain AppDomain { get; set; }
    }
    
    private void OnPluginFileCreated(object sender, FileSystemEventArgs e)
    {
        // 延迟加载,避免文件锁定
        Task.Delay(1000).ContinueWith(_ => LoadPlugin(e.FullPath));
    }
    
    private void OnPluginFileDeleted(object sender, FileSystemEventArgs e)
    {
        var pluginName = Path.GetFileNameWithoutExtension(e.Name);
        if (_loadedPlugins.ContainsKey(pluginName))
        {
            UnloadPlugin(pluginName);
        }
    }
    
    private void OnPluginFileChanged(object sender, FileSystemEventArgs e)
    {
        // 热重载:先卸载再重新加载
        var pluginName = Path.GetFileNameWithoutExtension(e.Name);
        if (_loadedPlugins.ContainsKey(pluginName))
        {
            UnloadPlugin(pluginName);
            Task.Delay(1000).ContinueWith(_ => LoadPlugin(e.FullPath));
        }
    }
    
    public void LoadPlugin(string pluginPath)
    {
        try
        {
            // 在独立AppDomain中加载插件,实现完全隔离
            var setup = new AppDomainSetup
            {
                ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
                PrivateBinPath = Path.GetDirectoryName(pluginPath)
            };
            
            var appDomain = AppDomain.CreateDomain(
                $"PluginDomain_{Path.GetFileNameWithoutExtension(pluginPath)}",
                null, setup);
            
            var loader = (PluginLoaderProxy)appDomain.CreateInstanceAndUnwrap(
                typeof(PluginLoaderProxy).Assembly.FullName,
                typeof(PluginLoaderProxy).FullName);
            
            var plugin = loader.LoadPlugin(pluginPath);
            
            var context = new PluginContext
            {
                Assembly = plugin.GetType().Assembly,
                PluginInstance = plugin,
                LastLoadTime = DateTime.Now,
                AppDomain = appDomain
            };
            
            _loadedPlugins[plugin.Name] = context;
            plugin.Initialize();
            
            Console.WriteLine($"Plugin {plugin.Name} loaded successfully.");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Failed to load plugin {pluginPath}: {ex.Message}");
        }
    }
    
    public void UnloadPlugin(string pluginName)
    {
        if (_loadedPlugins.TryGetValue(pluginName, out var context))
        {
            try
            {
                context.PluginInstance.Cleanup();
                AppDomain.Unload(context.AppDomain);
                _loadedPlugins.Remove(pluginName);
                Console.WriteLine($"Plugin {pluginName} unloaded successfully.");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Failed to unload plugin {pluginName}: {ex.Message}");
            }
        }
    }
    
    // 代理类,用于跨AppDomain通信
    [Serializable]
    public class PluginLoaderProxy : MarshalByRefObject
    {
        public IPlugin LoadPlugin(string assemblyPath)
        {
            var assembly = Assembly.LoadFrom(assemblyPath);
            
            foreach (var type in assembly.GetExportedTypes())
            {
                if (typeof(IPlugin).IsAssignableFrom(type) && !type.IsAbstract)
                {
                    return (IPlugin)Activator.CreateInstance(type);
                }
            }
            
            throw new InvalidOperationException("No IPlugin implementation found.");
        }
    }
    
    public void Dispose()
    {
        _fileWatcher?.Dispose();
        
        // 清理所有插件
        foreach (var pluginName in _loadedPlugins.Keys.ToList())
        {
            UnloadPlugin(pluginName);
        }
    }
}

🏗️ 插件系统的核心架构

插件系统架构图

复制代码
┌─────────────────────────────────────────────────────┐
│                  宿主应用程序(Host)                   │
├─────────────────────────────────────────────────────┤
│  ┌────────────┐  ┌────────────┐  ┌────────────┐   │
│  │  插件管理器 │  │  配置管理器 │  │  生命周期管理 │   │
│  └────────────┘  └────────────┘  └────────────┘   │
├─────────────────────────────────────────────────────┤
│              插件接口层(Contracts/Interfaces)        │
├─────────────────────────────────────────────────────┤
│  ┌────────────┐  ┌────────────┐  ┌────────────┐   │
│  │  插件A     │  │  插件B     │  │  插件C     │   │
│  │ (DLL/SO)   │  │ (DLL/SO)   │  │ (DLL/SO)   │   │
│  └────────────┘  └────────────┘  └────────────┘   │
└─────────────────────────────────────────────────────┘

关键组件设计

1. 插件发现机制
csharp 复制代码
// 基于反射的插件发现
public class PluginDiscoveryService
{
    private readonly List<IPlugin> _plugins = new List<IPlugin>();
    private readonly List<PluginMetadata> _metadata = new List<PluginMetadata>();
    
    public void DiscoverPlugins(string directory)
    {
        var dllFiles = Directory.GetFiles(directory, "*.dll");
        
        foreach (var dll in dllFiles)
        {
            try
            {
                var assembly = Assembly.LoadFrom(dll);
                DiscoverPluginsInAssembly(assembly);
            }
            catch (Exception ex)
            {
                LogWarning($"Failed to load assembly {dll}: {ex.Message}");
            }
        }
    }
    
    private void DiscoverPluginsInAssembly(Assembly assembly)
    {
        foreach (var type in assembly.GetTypes())
        {
            // 检查是否实现了IPlugin接口
            if (typeof(IPlugin).IsAssignableFrom(type) && 
                !type.IsAbstract && 
                type.IsClass)
            {
                // 检查是否有插件元数据
                var metadataAttr = type.GetCustomAttribute<PluginMetadataAttribute>();
                
                var metadata = new PluginMetadata
                {
                    Type = type,
                    Name = metadataAttr?.Name ?? type.Name,
                    Version = metadataAttr?.Version ?? new Version(1, 0),
                    Author = metadataAttr?.Author ?? "Unknown",
                    Description = metadataAttr?.Description ?? string.Empty,
                    Assembly = assembly
                };
                
                _metadata.Add(metadata);
            }
        }
    }
    
    public IPlugin InstantiatePlugin(PluginMetadata metadata)
    {
        try
        {
            var plugin = (IPlugin)Activator.CreateInstance(metadata.Type);
            _plugins.Add(plugin);
            return plugin;
        }
        catch (Exception ex)
        {
            throw new PluginInstantiationException(
                $"Failed to instantiate plugin {metadata.Name}", ex);
        }
    }
    
    public IEnumerable<PluginMetadata> GetAvailablePlugins()
    {
        return _metadata.AsReadOnly();
    }
    
    public IEnumerable<IPlugin> GetLoadedPlugins()
    {
        return _plugins.AsReadOnly();
    }
}

// 插件依赖关系解析
public class PluginDependencyResolver
{
    public class DependencyGraph
    {
        public Dictionary<string, List<string>> Dependencies { get; } = new();
        public Dictionary<string, List<string>> Dependents { get; } = new();
    }
    
    public DependencyGraph BuildDependencyGraph(IEnumerable<PluginMetadata> plugins)
    {
        var graph = new DependencyGraph();
        
        foreach (var plugin in plugins)
        {
            var deps = GetPluginDependencies(plugin);
            graph.Dependencies[plugin.Name] = deps;
            
            // 更新反向依赖
            foreach (var dep in deps)
            {
                if (!graph.Dependents.ContainsKey(dep))
                    graph.Dependents[dep] = new List<string>();
                
                graph.Dependents[dep].Add(plugin.Name);
            }
        }
        
        return graph;
    }
    
    public List<string> GetLoadOrder(DependencyGraph graph)
    {
        var loadOrder = new List<string>();
        var visited = new HashSet<string>();
        var tempMarks = new HashSet<string>();
        
        foreach (var plugin in graph.Dependencies.Keys)
        {
            if (!visited.Contains(plugin))
            {
                Visit(plugin, graph, visited, tempMarks, loadOrder);
            }
        }
        
        return loadOrder;
    }
    
    private void Visit(string plugin, DependencyGraph graph, 
                      HashSet<string> visited, HashSet<string> tempMarks,
                      List<string> loadOrder)
    {
        if (tempMarks.Contains(plugin))
            throw new CircularDependencyException($"Circular dependency detected involving {plugin}");
        
        if (!visited.Contains(plugin))
        {
            tempMarks.Add(plugin);
            
            if (graph.Dependencies.ContainsKey(plugin))
            {
                foreach (var dependency in graph.Dependencies[plugin])
                {
                    Visit(dependency, graph, visited, tempMarks, loadOrder);
                }
            }
            
            tempMarks.Remove(plugin);
            visited.Add(plugin);
            loadOrder.Add(plugin);
        }
    }
    
    private List<string> GetPluginDependencies(PluginMetadata plugin)
    {
        // 从插件元数据或特性中获取依赖信息
        var deps = new List<string>();
        var depsAttr = plugin.Type.GetCustomAttribute<PluginDependenciesAttribute>();
        
        if (depsAttr != null)
        {
            deps.AddRange(depsAttr.RequiredPlugins);
        }
        
        return deps;
    }
}
2. 插件生命周期管理
csharp 复制代码
// 完整的插件生命周期管理器
public class PluginLifecycleManager : IDisposable
{
    public enum PluginState
    {
        NotLoaded,
        Loading,
        Loaded,
        Initializing,
        Initialized,
        Executing,
        Error,
        Unloading,
        Unloaded
    }
    
    public class PluginContext
    {
        public IPlugin Plugin { get; set; }
        public PluginMetadata Metadata { get; set; }
        public PluginState State { get; set; }
        public DateTime LoadTime { get; set; }
        public Exception LastError { get; set; }
        public PerformanceMetrics Metrics { get; set; }
        public List<string> Dependencies { get; set; }
        public List<string> Dependents { get; set; }
    }
    
    public class PerformanceMetrics
    {
        public TimeSpan LoadTime { get; set; }
        public TimeSpan InitializeTime { get; set; }
        public TimeSpan AverageExecutionTime { get; set; }
        public int ExecutionCount { get; set; }
        public DateTime LastExecution { get; set; }
    }
    
    private readonly Dictionary<string, PluginContext> _plugins;
    private readonly IPluginDiscoveryService _discoveryService;
    private readonly PluginDependencyResolver _dependencyResolver;
    private readonly object _lock = new object();
    
    public PluginLifecycleManager(string pluginsDirectory)
    {
        _plugins = new Dictionary<string, PluginContext>();
        _discoveryService = new PluginDiscoveryService();
        _dependencyResolver = new PluginDependencyResolver();
        
        InitializePluginSystem(pluginsDirectory);
    }
    
    private void InitializePluginSystem(string pluginsDirectory)
    {
        // 发现所有可用插件
        _discoveryService.DiscoverPlugins(pluginsDirectory);
        
        // 构建依赖图
        var availablePlugins = _discoveryService.GetAvailablePlugins().ToList();
        var dependencyGraph = _dependencyResolver.BuildDependencyGraph(availablePlugins);
        
        // 获取加载顺序
        var loadOrder = _dependencyResolver.GetLoadOrder(dependencyGraph);
        
        // 按顺序初始化上下文
        foreach (var pluginName in loadOrder)
        {
            var metadata = availablePlugins.First(p => p.Name == pluginName);
            
            var context = new PluginContext
            {
                Metadata = metadata,
                State = PluginState.NotLoaded,
                Dependencies = dependencyGraph.Dependencies.ContainsKey(pluginName) 
                    ? dependencyGraph.Dependencies[pluginName] 
                    : new List<string>(),
                Dependents = dependencyGraph.Dependents.ContainsKey(pluginName) 
                    ? dependencyGraph.Dependents[pluginName] 
                    : new List<string>(),
                Metrics = new PerformanceMetrics()
            };
            
            _plugins[pluginName] = context;
        }
    }
    
    public async Task LoadPluginAsync(string pluginName)
    {
        lock (_lock)
        {
            if (!_plugins.ContainsKey(pluginName))
                throw new PluginNotFoundException($"Plugin {pluginName} not found");
            
            var context = _plugins[pluginName];
            
            if (context.State != PluginState.NotLoaded && 
                context.State != PluginState.Error)
                throw new InvalidOperationException($"Plugin is in {context.State} state");
            
            context.State = PluginState.Loading;
        }
        
        try
        {
            // 加载依赖
            await LoadDependenciesAsync(pluginName);
            
            // 加载插件本身
            var context = _plugins[pluginName];
            var stopwatch = Stopwatch.StartNew();
            
            context.Plugin = _discoveryService.InstantiatePlugin(context.Metadata);
            context.State = PluginState.Loaded;
            context.LoadTime = DateTime.Now;
            context.Metrics.LoadTime = stopwatch.Elapsed;
            
            // 初始化插件
            await InitializePluginAsync(pluginName);
            
            LogInfo($"Plugin {pluginName} loaded and initialized successfully");
        }
        catch (Exception ex)
        {
            _plugins[pluginName].State = PluginState.Error;
            _plugins[pluginName].LastError = ex;
            throw new PluginLoadException($"Failed to load plugin {pluginName}", ex);
        }
    }
    
    private async Task LoadDependenciesAsync(string pluginName)
    {
        var context = _plugins[pluginName];
        
        foreach (var dependency in context.Dependencies)
        {
            if (_plugins.TryGetValue(dependency, out var depContext))
            {
                if (depContext.State != PluginState.Initialized)
                {
                    await LoadPluginAsync(dependency);
                }
            }
            else
            {
                throw new DependencyNotFoundException(
                    $"Dependency {dependency} not found for plugin {pluginName}");
            }
        }
    }
    
    private async Task InitializePluginAsync(string pluginName)
    {
        var context = _plugins[pluginName];
        context.State = PluginState.Initializing;
        
        try
        {
            var stopwatch = Stopwatch.StartNew();
            
            if (context.Plugin is IAsyncInitializable asyncPlugin)
            {
                await asyncPlugin.InitializeAsync();
            }
            else
            {
                context.Plugin.Initialize();
            }
            
            context.State = PluginState.Initialized;
            context.Metrics.InitializeTime = stopwatch.Elapsed;
        }
        catch (Exception ex)
        {
            context.State = PluginState.Error;
            context.LastError = ex;
            throw;
        }
    }
    
    public async Task ExecutePluginAsync(string pluginName, object parameters = null)
    {
        var context = _plugins[pluginName];
        
        if (context.State != PluginState.Initialized)
            throw new InvalidOperationException($"Plugin is in {context.State} state");
        
        context.State = PluginState.Executing;
        
        try
        {
            var stopwatch = Stopwatch.StartNew();
            
            if (context.Plugin is IAsyncPlugin asyncPlugin)
            {
                await asyncPlugin.ExecuteAsync(parameters);
            }
            else
            {
                context.Plugin.Execute();
            }
            
            // 更新性能指标
            context.Metrics.ExecutionCount++;
            context.Metrics.LastExecution = DateTime.Now;
            context.Metrics.AverageExecutionTime = TimeSpan.FromTicks(
                (context.Metrics.AverageExecutionTime.Ticks * (context.Metrics.ExecutionCount - 1) 
                 + stopwatch.Elapsed.Ticks) / context.Metrics.ExecutionCount);
            
            context.State = PluginState.Initialized;
        }
        catch (Exception ex)
        {
            context.State = PluginState.Error;
            context.LastError = ex;
            throw new PluginExecutionException(
                $"Plugin {pluginName} execution failed", ex);
        }
    }
    
    public void Dispose()
    {
        // 按依赖关系的逆序卸载所有插件
        var unloadOrder = _plugins.Keys
            .OrderByDescending(name => _plugins[name].Dependents.Count)
            .ToList();
        
        foreach (var pluginName in unloadOrder)
        {
            if (_plugins[pluginName].State == PluginState.Initialized)
            {
                UnloadPlugin(pluginName);
            }
        }
    }
}
3. 插件通信机制
csharp 复制代码
// 插件间通信系统
public class PluginCommunicationBus
{
    public interface IPluginMessage
    {
        string Source { get; }
        string MessageType { get; }
        DateTime Timestamp { get; }
    }
    
    public abstract class PluginMessage : IPluginMessage
    {
        public string Source { get; }
        public string MessageType { get; }
        public DateTime Timestamp { get; }
        
        protected PluginMessage(string source, string messageType)
        {
            Source = source;
            MessageType = messageType;
            Timestamp = DateTime.UtcNow;
        }
    }
    
    public class EventMessage : PluginMessage
    {
        public string EventName { get; }
        public Dictionary<string, object> Data { get; }
        
        public EventMessage(string source, string eventName, 
                           Dictionary<string, object> data = null) 
            : base(source, "Event")
        {
            EventName = eventName;
            Data = data ?? new Dictionary<string, object>();
        }
    }
    
    public class RequestMessage : PluginMessage
    {
        public string RequestId { get; }
        public string Method { get; }
        public object[] Parameters { get; }
        
        public RequestMessage(string source, string method, 
                             object[] parameters, string requestId = null) 
            : base(source, "Request")
        {
            Method = method;
            Parameters = parameters;
            RequestId = requestId ?? Guid.NewGuid().ToString();
        }
    }
    
    public class ResponseMessage : PluginMessage
    {
        public string RequestId { get; }
        public object Result { get; }
        public Exception Error { get; }
        
        public ResponseMessage(string source, string requestId, 
                              object result = null, Exception error = null) 
            : base(source, "Response")
        {
            RequestId = requestId;
            Result = result;
            Error = error;
        }
    }
    
    // 消息处理器
    public delegate Task MessageHandler<T>(T message) where T : IPluginMessage;
    
    private readonly Dictionary<string, List<Delegate>> _handlers;
    private readonly Dictionary<string, TaskCompletionSource<object>> _pendingRequests;
    private readonly IPluginLifecycleManager _lifecycleManager;
    
    public PluginCommunicationBus(IPluginLifecycleManager lifecycleManager)
    {
        _handlers = new Dictionary<string, List<Delegate>>();
        _pendingRequests = new Dictionary<string, TaskCompletionSource<object>>();
        _lifecycleManager = lifecycleManager;
    }
    
    public void Subscribe<T>(string messageType, MessageHandler<T> handler) 
        where T : IPluginMessage
    {
        if (!_handlers.ContainsKey(messageType))
            _handlers[messageType] = new List<Delegate>();
        
        _handlers[messageType].Add(handler);
    }
    
    public void Unsubscribe<T>(string messageType, MessageHandler<T> handler) 
        where T : IPluginMessage
    {
        if (_handlers.ContainsKey(messageType))
        {
            _handlers[messageType].Remove(handler);
        }
    }
    
    public async Task PublishAsync(IPluginMessage message)
    {
        var messageType = message.MessageType;
        
        if (_handlers.ContainsKey(messageType))
        {
            var tasks = new List<Task>();
            
            foreach (var handler in _handlers[messageType])
            {
                try
                {
                    // 动态调用处理程序
                    var task = (Task)handler.DynamicInvoke(message);
                    tasks.Add(task);
                }
                catch (Exception ex)
                {
                    LogError($"Error in message handler: {ex.Message}");
                }
            }
            
            await Task.WhenAll(tasks);
        }
        
        // 特殊处理响应消息
        if (message is ResponseMessage response && 
            _pendingRequests.TryGetValue(response.RequestId, out var tcs))
        {
            if (response.Error != null)
                tcs.TrySetException(response.Error);
            else
                tcs.TrySetResult(response.Result);
        }
    }
    
    public async Task<T> RequestAsync<T>(string targetPlugin, string method, 
                                        object[] parameters, 
                                        TimeSpan timeout = default)
    {
        var requestId = Guid.NewGuid().ToString();
        var request = new RequestMessage(targetPlugin, method, parameters, requestId);
        var tcs = new TaskCompletionSource<object>();
        
        _pendingRequests[requestId] = tcs;
        
        // 设置超时
        var timeoutTask = Task.Delay(timeout == default ? TimeSpan.FromSeconds(30) : timeout)
            .ContinueWith(_ => 
                new TimeoutException($"Request to {targetPlugin}.{method} timed out"));
        
        try
        {
            await PublishAsync(request);
            
            var completedTask = await Task.WhenAny(tcs.Task, timeoutTask);
            
            if (completedTask == timeoutTask)
                throw await timeoutTask;
            
            var result = await tcs.Task;
            
            if (result is T typedResult)
                return typedResult;
            
            throw new InvalidCastException($"Cannot cast result to {typeof(T).Name}");
        }
        finally
        {
            _pendingRequests.Remove(requestId);
        }
    }
    
    // 插件注册通信端点
    public void RegisterPluginEndpoints(string pluginName, IPlugin plugin)
    {
        // 自动发现插件中的消息处理方法
        var methods = plugin.GetType().GetMethods(BindingFlags.Instance | 
                                                 BindingFlags.Public | 
                                                 BindingFlags.NonPublic);
        
        foreach (var method in methods)
        {
            var messageHandlerAttr = method.GetCustomAttribute<MessageHandlerAttribute>();
            if (messageHandlerAttr != null)
            {
                var messageType = messageHandlerAttr.MessageType;
                
                // 创建委托
                var handlerType = typeof(MessageHandler<>)
                    .MakeGenericType(method.GetParameters()[0].ParameterType);
                
                var handler = Delegate.CreateDelegate(handlerType, plugin, method);
                
                Subscribe(messageType, handler);
            }
        }
    }
}

// 消息处理特性
[AttributeUsage(AttributeTargets.Method)]
public class MessageHandlerAttribute : Attribute
{
    public string MessageType { get; }
    
    public MessageHandlerAttribute(string messageType)
    {
        MessageType = messageType;
    }
}

// 使用示例
public class DataProcessorPlugin : IPlugin
{
    [MessageHandler("DataProcessingRequest")]
    public async Task HandleDataRequest(RequestMessage request)
    {
        if (request.Method == "ProcessData")
        {
            var data = request.Parameters[0] as string;
            var processed = await ProcessDataAsync(data);
            
            // 发送响应
            var response = new ResponseMessage("DataProcessorPlugin", 
                request.RequestId, processed);
            
            // 通过通信总线发送响应
            // _communicationBus.PublishAsync(response);
        }
    }
    
    private async Task<string> ProcessDataAsync(string data)
    {
        await Task.Delay(100); // 模拟处理时间
        return $"Processed: {data}";
    }
}

💻 实践篇:C# 下的插件式开发

1. 定义插件契约

csharp 复制代码
// 核心插件契约
namespace PluginFramework
{
    // 基础插件接口
    public interface IPlugin : IDisposable
    {
        /// <summary>
        /// 插件唯一标识
        /// </summary>
        string Id { get; }
        
        /// <summary>
        /// 插件显示名称
        /// </summary>
        string Name { get; }
        
        /// <summary>
        /// 插件版本
        /// </summary>
        Version Version { get; }
        
        /// <summary>
        /// 插件描述
        /// </summary>
        string Description { get; }
        
        /// <summary>
        /// 插件作者
        /// </summary>
        string Author { get; }
        
        /// <summary>
        /// 插件配置
        /// </summary>
        IPluginConfiguration Configuration { get; }
        
        /// <summary>
        /// 初始化插件
        /// </summary>
        /// <param name="context">插件上下文</param>
        void Initialize(IPluginContext context);
        
        /// <summary>
        /// 启动插件
        /// </summary>
        void Start();
        
        /// <summary>
        /// 停止插件
        /// </summary>
        void Stop();
        
        /// <summary>
        /// 获取插件状态
        /// </summary>
        PluginStatus GetStatus();
    }
    
    // 插件状态枚举
    public enum PluginStatus
    {
        NotLoaded,
        Loaded,
        Initialized,
        Running,
        Stopped,
        Error,
        Disposed
    }
    
    // 插件上下文接口
    public interface IPluginContext
    {
        /// <summary>
        /// 宿主程序信息
        /// </summary>
        IHostInfo HostInfo { get; }
        
        /// <summary>
        /// 日志记录器
        /// </summary>
        ILogger Logger { get; }
        
        /// <summary>
        /// 配置管理器
        /// </summary>
        IConfigurationManager ConfigurationManager { get; }
        
        /// <summary>
        /// 服务容器
        /// </summary>
        IServiceProvider ServiceProvider { get; }
        
        /// <summary>
        /// 事件总线
        /// </summary>
        IEventBus EventBus { get; }
        
        /// <summary>
        /// 获取其他插件
        /// </summary>
        IPlugin GetPlugin(string pluginId);
        
        /// <summary>
        /// 获取所有插件
        /// </summary>
        IEnumerable<IPlugin> GetAllPlugins();
    }
    
    // 配置相关接口
    public interface IPluginConfiguration
    {
        T GetSetting<T>(string key, T defaultValue = default);
        void SetSetting<T>(string key, T value);
        bool HasSetting(string key);
        void Save();
        void Load();
    }
    
    // 支持异步操作的插件接口
    public interface IAsyncPlugin : IPlugin
    {
        Task InitializeAsync(IPluginContext context, CancellationToken cancellationToken = default);
        Task StartAsync(CancellationToken cancellationToken = default);
        Task StopAsync(CancellationToken cancellationToken = default);
    }
    
    // 支持UI的插件接口
    public interface IUIPlugin : IPlugin
    {
        /// <summary>
        /// 插件UI元素
        /// </summary>
        UIElement GetUIElement();
        
        /// <summary>
        /// UI显示位置
        /// </summary>
        UILocation PreferredLocation { get; }
        
        /// <summary>
        /// UI大小
        /// </summary>
        Size PreferredSize { get; }
    }
    
    // UI位置枚举
    public enum UILocation
    {
        MainWindow,
        SidePanel,
        Toolbar,
        StatusBar,
        Dialog,
        ContextMenu
    }
    
    // 支持命令的插件接口
    public interface ICommandPlugin : IPlugin
    {
        /// <summary>
        /// 插件提供的命令
        /// </summary>
        IEnumerable<ICommand> Commands { get; }
        
        /// <summary>
        /// 执行命令
        /// </summary>
        Task<CommandResult> ExecuteCommand(string commandId, 
                                          Dictionary<string, object> parameters = null);
    }
    
    // 命令接口
    public interface ICommand
    {
        string Id { get; }
        string Name { get; }
        string Description { get; }
        string Icon { get; }
        bool CanExecute(object parameter);
        Task ExecuteAsync(object parameter);
    }
    
    // 命令结果
    public class CommandResult
    {
        public bool Success { get; set; }
        public string Message { get; set; }
        public object Data { get; set; }
        public Exception Error { get; set; }
        
        public static CommandResult Ok(string message = null, object data = null)
            => new CommandResult { Success = true, Message = message, Data = data };
        
        public static CommandResult Fail(string message, Exception error = null)
            => new CommandResult { Success = false, Message = message, Error = error };
    }
}

// 插件元数据特性
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class PluginMetadataAttribute : Attribute
{
    public string Id { get; }
    public string Name { get; }
    public string Version { get; }
    public string Description { get; }
    public string Author { get; }
    public string[] Dependencies { get; set; }
    public string[] Tags { get; set; }
    public string Icon { get; set; }
    public string Website { get; set; }
    public string License { get; set; }
    
    public PluginMetadataAttribute(string id, string name, string version, 
                                  string description = "", string author = "")
    {
        Id = id ?? throw new ArgumentNullException(nameof(id));
        Name = name ?? throw new ArgumentNullException(nameof(name));
        Version = version ?? throw new ArgumentNullException(nameof(version));
        Description = description;
        Author = author;
        Dependencies = Array.Empty<string>();
        Tags = Array.Empty<string>();
    }
}

// 插件依赖特性
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class PluginDependencyAttribute : Attribute
{
    public string PluginId { get; }
    public string MinVersion { get; }
    public string MaxVersion { get; }
    public bool Optional { get; set; }
    
    public PluginDependencyAttribute(string pluginId, 
                                    string minVersion = null, 
                                    string maxVersion = null)
    {
        PluginId = pluginId;
        MinVersion = minVersion;
        MaxVersion = maxVersion;
    }
}

// 插件初始化特性
[AttributeUsage(AttributeTargets.Method)]
public class PluginInitializerAttribute : Attribute
{
    public InitializationStage Stage { get; }
    public int Order { get; set; }
    
    public PluginInitializerAttribute(InitializationStage stage = InitializationStage.Normal)
    {
        Stage = stage;
    }
}

public enum InitializationStage
{
    Early,      // 早期初始化
    Normal,     // 正常初始化
    Late        // 后期初始化
}

2. 实现一个具体插件

csharp 复制代码
// 示例:图片处理插件
[PluginMetadata(
    id: "com.example.imageprocessor",
    name: "Image Processor Plugin",
    version: "1.2.0",
    description: "Provides image processing functionality",
    author: "Example Corp",
    Tags = new[] { "image", "processing", "filter" },
    Icon = "icon.png",
    Website = "https://example.com/plugins/image-processor",
    License = "MIT"
)]
[PluginDependency("com.example.core", "1.0.0")]
[PluginDependency("com.example.ui", "2.0.0", Optional = true)]
public class ImageProcessorPlugin : IPlugin, ICommandPlugin, IUIPlugin
{
    // 插件状态
    private PluginStatus _status = PluginStatus.NotLoaded;
    private IPluginContext _context;
    private readonly List<ICommand> _commands = new List<ICommand>();
    private ImageProcessor _processor;
    private ImageProcessorUI _ui;
    
    // IPlugin 实现
    public string Id => "com.example.imageprocessor";
    public string Name => "Image Processor Plugin";
    public Version Version => new Version(1, 2, 0);
    public string Description => "Provides image processing functionality";
    public string Author => "Example Corp";
    public IPluginConfiguration Configuration { get; private set; }
    
    public void Initialize(IPluginContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
        
        try
        {
            // 初始化配置
            Configuration = new JsonPluginConfiguration("imageprocessor.config.json");
            Configuration.Load();
            
            // 初始化处理器
            _processor = new ImageProcessor(Configuration);
            
            // 注册命令
            InitializeCommands();
            
            // 初始化UI
            _ui = new ImageProcessorUI(_processor);
            
            // 订阅事件
            context.EventBus.Subscribe<ImageLoadedEvent>(OnImageLoaded);
            context.EventBus.Subscribe<ApplicationShutdownEvent>(OnShutdown);
            
            _status = PluginStatus.Initialized;
            _context.Logger.Info($"Plugin {Name} initialized successfully");
        }
        catch (Exception ex)
        {
            _status = PluginStatus.Error;
            _context.Logger.Error($"Failed to initialize plugin {Name}: {ex}");
            throw new PluginInitializationException($"Failed to initialize {Name}", ex);
        }
    }
    
    private void InitializeCommands()
    {
        _commands.Add(new ApplyFilterCommand(_processor));
        _commands.Add(new ResizeImageCommand(_processor));
        _commands.Add(new ConvertFormatCommand(_processor));
        _commands.Add(new BatchProcessCommand(_processor));
    }
    
    [PluginInitializer(InitializationStage.Late, Order = 100)]
    private void InitializeUIComponents()
    {
        // 延迟初始化UI组件
        if (_context.ServiceProvider.GetService(typeof(IUIService)) is IUIService uiService)
        {
            uiService.RegisterToolbarItem(new ToolbarItem
            {
                Id = "image-processor-tools",
                Title = "Image Tools",
                Icon = "image.png",
                Command = new RelayCommand(() => ShowProcessorDialog())
            });
        }
    }
    
    public void Start()
    {
        if (_status != PluginStatus.Initialized && _status != PluginStatus.Stopped)
            throw new InvalidOperationException($"Plugin is in {_status} state");
        
        try
        {
            _processor.Start();
            _status = PluginStatus.Running;
            _context.Logger.Info($"Plugin {Name} started");
        }
        catch (Exception ex)
        {
            _status = PluginStatus.Error;
            _context.Logger.Error($"Failed to start plugin {Name}: {ex}");
            throw;
        }
    }
    
    public void Stop()
    {
        if (_status != PluginStatus.Running)
            return;
        
        try
        {
            _processor.Stop();
            _status = PluginStatus.Stopped;
            _context.Logger.Info($"Plugin {Name} stopped");
        }
        catch (Exception ex)
        {
            _context.Logger.Error($"Error stopping plugin {Name}: {ex}");
        }
    }
    
    public PluginStatus GetStatus() => _status;
    
    // ICommandPlugin 实现
    public IEnumerable<ICommand> Commands => _commands.AsReadOnly();
    
    public async Task<CommandResult> ExecuteCommand(string commandId, 
                                                   Dictionary<string, object> parameters = null)
    {
        var command = _commands.FirstOrDefault(c => c.Id == commandId);
        if (command == null)
            return CommandResult.Fail($"Command {commandId} not found");
        
        try
        {
            await command.ExecuteAsync(parameters);
            return CommandResult.Ok($"Command {commandId} executed successfully");
        }
        catch (Exception ex)
        {
            return CommandResult.Fail($"Command {commandId} failed: {ex.Message}", ex);
        }
    }
    
    // IUIPlugin 实现
    public UIElement GetUIElement() => _ui?.CreateUI();
    
    public UILocation PreferredLocation => UILocation.SidePanel;
    
    public Size PreferredSize => new Size(300, 500);
    
    // 事件处理
    private void OnImageLoaded(ImageLoadedEvent e)
    {
        if (_status == PluginStatus.Running)
        {
            // 自动处理新加载的图片
            Task.Run(async () =>
            {
                try
                {
                    var processed = await _processor.AutoProcessAsync(e.ImagePath);
                    _context.EventBus.Publish(new ImageProcessedEvent
                    {
                        OriginalPath = e.ImagePath,
                        ProcessedPath = processed,
                        Processor = Name
                    });
                }
                catch (Exception ex)
                {
                    _context.Logger.Error($"Auto-processing failed for {e.ImagePath}: {ex}");
                }
            });
        }
    }
    
    private void OnShutdown(ApplicationShutdownEvent e)
    {
        Stop();
    }
    
    // 清理资源
    private bool _disposed = false;
    
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    
    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                Stop();
                
                _processor?.Dispose();
                _ui?.Dispose();
                
                foreach (var command in _commands.OfType<IDisposable>())
                {
                    command.Dispose();
                }
                
                _context?.EventBus.Unsubscribe<ImageLoadedEvent>(OnImageLoaded);
                _context?.EventBus.Unsubscribe<ApplicationShutdownEvent>(OnShutdown);
            }
            
            _disposed = true;
            _status = PluginStatus.Disposed;
        }
    }
    
    ~ImageProcessorPlugin()
    {
        Dispose(false);
    }
    
    // 内部命令类
    private class ApplyFilterCommand : ICommand
    {
        private readonly ImageProcessor _processor;
        
        public ApplyFilterCommand(ImageProcessor processor)
        {
            _processor = processor;
            Id = "apply-filter";
            Name = "Apply Filter";
            Description = "Apply image filter";
            Icon = "filter.png";
        }
        
        public string Id { get; }
        public string Name { get; }
        public string Description { get; }
        public string Icon { get; }
        
        public bool CanExecute(object parameter) => true;
        
        public async Task ExecuteAsync(object parameter)
        {
            if (parameter is ImageProcessingParams args)
            {
                await _processor.ApplyFilterAsync(args);
            }
        }
    }
    
    // 更多命令类...
}

// 图像处理器实现
public class ImageProcessor : IDisposable
{
    private readonly IPluginConfiguration _configuration;
    private readonly ConcurrentQueue<ImageTask> _taskQueue;
    private readonly CancellationTokenSource _cts;
    private Task _processingTask;
    
    public ImageProcessor(IPluginConfiguration configuration)
    {
        _configuration = configuration;
        _taskQueue = new ConcurrentQueue<ImageTask>();
        _cts = new CancellationTokenSource();
    }
    
    public void Start()
    {
        _processingTask = Task.Run(async () => await ProcessQueueAsync(_cts.Token));
    }
    
    public void Stop()
    {
        _cts.Cancel();
        _processingTask?.Wait(TimeSpan.FromSeconds(5));
    }
    
    private async Task ProcessQueueAsync(CancellationToken cancellationToken)
    {
        while (!cancellationToken.IsCancellationRequested)
        {
            if (_taskQueue.TryDequeue(out var task))
            {
                try
                {
                    await ProcessImageAsync(task);
                }
                catch (Exception ex)
                {
                    task.CompletionSource.TrySetException(ex);
                }
            }
            else
            {
                await Task.Delay(100, cancellationToken);
            }
        }
    }
    
    public async Task<string> AutoProcessAsync(string imagePath)
    {
        var filters = _configuration.GetSetting<string[]>("autoFilters", 
                    new[] { "auto_contrast", "sharpen" });
        
        var outputDir = _configuration.GetSetting("outputDirectory", 
                    Path.Combine(Path.GetTempPath(), "processed_images"));
        
        Directory.CreateDirectory(outputDir);
        
        var outputPath = Path.Combine(outputDir, 
            $"{Path.GetFileNameWithoutExtension(imagePath)}_processed{Path.GetExtension(imagePath)}");
        
        await ApplyFiltersAsync(imagePath, outputPath, filters);
        
        return outputPath;
    }
    
    public async Task ApplyFilterAsync(ImageProcessingParams parameters)
    {
        using (var image = await LoadImageAsync(parameters.InputPath))
        {
            foreach (var filter in parameters.Filters)
            {
                image = await ApplyFilterInternalAsync(image, filter);
            }
            
            await SaveImageAsync(image, parameters.OutputPath);
        }
    }
    
    private async Task<Image> LoadImageAsync(string path)
    {
        return await Task.Run(() =>
        {
            // 使用System.Drawing或ImageSharp等库
            return Image.Load(path);
        });
    }
    
    public void Dispose()
    {
        _cts?.Cancel();
        _cts?.Dispose();
        _processingTask?.Dispose();
    }
}

// 配置类
public class JsonPluginConfiguration : IPluginConfiguration
{
    private readonly string _configPath;
    private Dictionary<string, object> _settings;
    private readonly object _lock = new object();
    
    public JsonPluginConfiguration(string configPath)
    {
        _configPath = configPath;
        _settings = new Dictionary<string, object>();
    }
    
    public T GetSetting<T>(string key, T defaultValue = default)
    {
        lock (_lock)
        {
            if (_settings.TryGetValue(key, out var value))
            {
                try
                {
                    return (T)Convert.ChangeType(value, typeof(T));
                }
                catch
                {
                    return defaultValue;
                }
            }
            return defaultValue;
        }
    }
    
    public void SetSetting<T>(string key, T value)
    {
        lock (_lock)
        {
            _settings[key] = value;
        }
    }
    
    public bool HasSetting(string key)
    {
        lock (_lock)
        {
            return _settings.ContainsKey(key);
        }
    }
    
    public void Save()
    {
        lock (_lock)
        {
            var json = JsonConvert.SerializeObject(_settings, Formatting.Indented);
            File.WriteAllText(_configPath, json);
        }
    }
    
    public void Load()
    {
        lock (_lock)
        {
            if (File.Exists(_configPath))
            {
                var json = File.ReadAllText(_configPath);
                _settings = JsonConvert.DeserializeObject<Dictionary<string, object>>(json) 
                          ?? new Dictionary<string, object>();
            }
        }
    }
}

3. 构建宿主程序(插件加载器)

csharp 复制代码
// 完整的插件宿主程序
namespace PluginHost
{
    public class PluginHostApplication : IDisposable
    {
        private readonly string _pluginsDirectory;
        private readonly ILogger _logger;
        private readonly IConfiguration _configuration;
        private readonly PluginManager _pluginManager;
        private readonly PluginLoader _pluginLoader;
        private readonly DependencyResolver _dependencyResolver;
        private readonly ServiceProvider _serviceProvider;
        private readonly EventAggregator _eventAggregator;
        private readonly UIManager _uiManager;
        private readonly CommandManager _commandManager;
        
        // 插件目录结构
        // plugins/
        //   ├── installed/          # 已安装插件
        //   ├── cache/             # 插件缓存
        //   ├── temp/              # 临时目录
        //   └── config/            # 插件配置
        
        public PluginHostApplication(string baseDirectory)
        {
            _pluginsDirectory = Path.Combine(baseDirectory, "plugins");
            
            // 初始化基础服务
            _logger = CreateLogger();
            _configuration = LoadConfiguration();
            _serviceProvider = ConfigureServices();
            
            // 初始化插件系统组件
            _pluginLoader = new PluginLoader(_pluginsDirectory, _logger);
            _dependencyResolver = new DependencyResolver(_logger);
            _eventAggregator = new EventAggregator(_logger);
            _uiManager = new UIManager(_serviceProvider);
            _commandManager = new CommandManager();
            
            // 初始化插件管理器
            _pluginManager = new PluginManager(
                _pluginLoader,
                _dependencyResolver,
                _eventAggregator,
                _uiManager,
                _commandManager,
                _logger,
                _configuration);
            
            EnsureDirectories();
        }
        
        private void EnsureDirectories()
        {
            var directories = new[]
            {
                _pluginsDirectory,
                Path.Combine(_pluginsDirectory, "installed"),
                Path.Combine(_pluginsDirectory, "cache"),
                Path.Combine(_pluginsDirectory, "temp"),
                Path.Combine(_pluginsDirectory, "config")
            };
            
            foreach (var dir in directories)
            {
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
            }
        }
        
        private ServiceProvider ConfigureServices()
        {
            var services = new ServiceCollection();
            
            // 注册核心服务
            services.AddSingleton<ILogger>(_logger);
            services.AddSingleton<IConfiguration>(_configuration);
            services.AddSingleton<IEventAggregator>(_eventAggregator);
            services.AddSingleton<IUIManager>(_uiManager);
            services.AddSingleton<ICommandManager>(_commandManager);
            
            // 注册文件服务
            services.AddSingleton<IFileSystem, PhysicalFileSystem>();
            
            // 注册插件相关服务
            services.AddSingleton<IPluginManager>(_pluginManager);
            services.AddSingleton<IPluginLoader>(_pluginLoader);
            services.AddSingleton<IPluginInstaller, PluginInstaller>();
            services.AddSingleton<IPluginUpdater, PluginUpdater>();
            
            return services.BuildServiceProvider();
        }
        
        public async Task InitializeAsync()
        {
            _logger.Info("Initializing plugin host application...");
            
            try
            {
                // 发现插件
                await _pluginLoader.DiscoverPluginsAsync();
                
                // 解析依赖
                var dependencyGraph = _dependencyResolver.BuildGraph(
                    _pluginLoader.GetDiscoveredPlugins());
                
                // 验证插件
                var validationResults = await ValidatePluginsAsync(
                    _pluginLoader.GetDiscoveredPlugins());
                
                // 初始化插件管理器
                await _pluginManager.InitializeAsync(dependencyGraph);
                
                // 加载核心插件
                await LoadCorePluginsAsync();
                
                // 初始化UI
                await _uiManager.InitializeAsync();
                
                _logger.Info("Plugin host application initialized successfully");
            }
            catch (Exception ex)
            {
                _logger.Error($"Failed to initialize plugin host: {ex}");
                throw;
            }
        }
        
        private async Task LoadCorePluginsAsync()
        {
            var corePlugins = _pluginLoader.GetDiscoveredPlugins()
                .Where(p => p.Tags?.Contains("core") == true)
                .OrderBy(p => p.LoadOrder);
            
            foreach (var pluginInfo in corePlugins)
            {
                try
                {
                    await _pluginManager.LoadPluginAsync(pluginInfo.Id);
                    _logger.Info($"Loaded core plugin: {pluginInfo.Name}");
                }
                catch (Exception ex)
                {
                    _logger.Error($"Failed to load core plugin {pluginInfo.Name}: {ex}");
                }
            }
        }
        
        public async Task StartAsync()
        {
            _logger.Info("Starting plugin host application...");
            
            try
            {
                // 启动所有已加载插件
                await _pluginManager.StartAllPluginsAsync();
                
                // 发布应用程序启动事件
                await _eventAggregator.PublishAsync(new ApplicationStartedEvent());
                
                _logger.Info("Plugin host application started successfully");
            }
            catch (Exception ex)
            {
                _logger.Error($"Failed to start plugin host: {ex}");
                throw;
            }
        }
        
        public async Task StopAsync()
        {
            _logger.Info("Stopping plugin host application...");
            
            try
            {
                // 发布应用程序停止事件
                await _eventAggregator.PublishAsync(new ApplicationStoppingEvent());
                
                // 停止所有插件(按依赖逆序)
                await _pluginManager.StopAllPluginsAsync();
                
                _logger.Info("Plugin host application stopped successfully");
            }
            catch (Exception ex)
            {
                _logger.Error($"Error stopping plugin host: {ex}");
            }
        }
        
        public async Task InstallPluginAsync(string pluginPackagePath)
        {
            var installer = _serviceProvider.GetRequiredService<IPluginInstaller>();
            await installer.InstallAsync(pluginPackagePath);
        }
        
        public async Task UninstallPluginAsync(string pluginId)
        {
            var installer = _serviceProvider.GetRequiredService<IPluginInstaller>();
            await installer.UninstallAsync(pluginId);
        }
        
        public async Task UpdatePluginAsync(string pluginId)
        {
            var updater = _serviceProvider.GetRequiredService<IPluginUpdater>();
            await updater.UpdateAsync(pluginId);
        }
        
        public IReadOnlyDictionary<string, PluginInfo> GetInstalledPlugins()
            => _pluginManager.GetInstalledPlugins();
        
        public IReadOnlyDictionary<string, PluginInfo> GetLoadedPlugins()
            => _pluginManager.GetLoadedPlugins();
        
        public PluginStatus GetPluginStatus(string pluginId)
            => _pluginManager.GetPluginStatus(pluginId);
        
        public void Dispose()
        {
            StopAsync().Wait(TimeSpan.FromSeconds(10));
            
            _pluginManager?.Dispose();
            _serviceProvider?.Dispose();
            _logger?.Dispose();
            
            GC.SuppressFinalize(this);
        }
    }
    
    // 插件管理器实现
    public class PluginManager : IPluginManager, IDisposable
    {
        private readonly IPluginLoader _loader;
        private readonly DependencyResolver _dependencyResolver;
        private readonly IEventAggregator _eventAggregator;
        private readonly IUIManager _uiManager;
        private readonly ICommandManager _commandManager;
        private readonly ILogger _logger;
        private readonly IConfiguration _configuration;
        
        private readonly Dictionary<string, PluginContext> _plugins;
        private readonly Dictionary<string, PluginInfo> _pluginInfos;
        private readonly PluginScheduler _scheduler;
        private readonly PluginMonitor _monitor;
        private readonly object _lock = new object();
        
        public PluginManager(
            IPluginLoader loader,
            DependencyResolver dependencyResolver,
            IEventAggregator eventAggregator,
            IUIManager uiManager,
            ICommandManager commandManager,
            ILogger logger,
            IConfiguration configuration)
        {
            _loader = loader;
            _dependencyResolver = dependencyResolver;
            _eventAggregator = eventAggregator;
            _uiManager = uiManager;
            _commandManager = commandManager;
            _logger = logger;
            _configuration = configuration;
            
            _plugins = new Dictionary<string, PluginContext>();
            _pluginInfos = new Dictionary<string, PluginInfo>();
            _scheduler = new PluginScheduler(logger);
            _monitor = new PluginMonitor(logger);
        }
        
        public async Task InitializeAsync(DependencyGraph dependencyGraph)
        {
            _logger.Info("Initializing plugin manager...");
            
            // 加载插件信息
            var discoveredPlugins = _loader.GetDiscoveredPlugins();
            foreach (var info in discoveredPlugins)
            {
                _pluginInfos[info.Id] = info;
            }
            
            // 初始化调度器
            await _scheduler.InitializeAsync();
            
            // 初始化监视器
            await _monitor.InitializeAsync();
            
            _logger.Info($"Plugin manager initialized with {discoveredPlugins.Count} plugins discovered");
        }
        
        public async Task LoadPluginAsync(string pluginId)
        {
            lock (_lock)
            {
                if (_plugins.ContainsKey(pluginId))
                    throw new PluginAlreadyLoadedException(pluginId);
            }
            
            if (!_pluginInfos.TryGetValue(pluginId, out var pluginInfo))
                throw new PluginNotFoundException(pluginId);
            
            _logger.Info($"Loading plugin: {pluginInfo.Name} v{pluginInfo.Version}");
            
            try
            {
                // 检查依赖
                await CheckDependenciesAsync(pluginId);
                
                // 创建插件上下文
                var context = new PluginContext
                {
                    PluginInfo = pluginInfo,
                    Status = PluginStatus.Loading,
                    LoadTime = DateTime.UtcNow
                };
                
                lock (_lock)
                {
                    _plugins[pluginId] = context;
                }
                
                // 加载插件程序集
                var assembly = await _loader.LoadPluginAssemblyAsync(pluginInfo);
                
                // 创建插件实例
                var plugin = CreatePluginInstance(assembly, pluginInfo);
                
                // 创建插件上下文
                var pluginContext = new PluginHostContext(
                    pluginId,
                    _eventAggregator,
                    _uiManager,
                    _commandManager,
                    _logger,
                    _configuration);
                
                // 初始化插件
                await InitializePluginAsync(plugin, pluginContext);
                
                context.Plugin = plugin;
                context.PluginHostContext = pluginContext;
                context.Status = PluginStatus.Loaded;
                
                // 注册UI组件
                RegisterPluginUI(plugin, pluginId);
                
                // 注册命令
                RegisterPluginCommands(plugin, pluginId);
                
                // 开始监视
                _monitor.StartMonitoring(pluginId, plugin);
                
                _logger.Info($"Plugin {pluginInfo.Name} loaded successfully");
                
                // 发布插件加载事件
                await _eventAggregator.PublishAsync(new PluginLoadedEvent
                {
                    PluginId = pluginId,
                    PluginName = pluginInfo.Name,
                    Version = pluginInfo.Version
                });
            }
            catch (Exception ex)
            {
                lock (_lock)
                {
                    _plugins.Remove(pluginId);
                }
                
                _logger.Error($"Failed to load plugin {pluginId}: {ex}");
                throw new PluginLoadException($"Failed to load plugin {pluginId}", ex);
            }
        }
        
        private async Task CheckDependenciesAsync(string pluginId)
        {
            var dependencies = _dependencyResolver.GetDependencies(pluginId);
            
            foreach (var dep in dependencies)
            {
                if (!_plugins.ContainsKey(dep))
                {
                    try
                    {
                        await LoadPluginAsync(dep);
                    }
                    catch (Exception ex)
                    {
                        throw new DependencyLoadException(
                            $"Failed to load dependency {dep} for plugin {pluginId}", ex);
                    }
                }
            }
        }
        
        private IPlugin CreatePluginInstance(Assembly assembly, PluginInfo pluginInfo)
        {
            var pluginType = assembly.GetTypes()
                .FirstOrDefault(t => typeof(IPlugin).IsAssignableFrom(t) && 
                                   !t.IsAbstract);
            
            if (pluginType == null)
                throw new InvalidPluginException($"No IPlugin implementation found in {assembly.FullName}");
            
            try
            {
                return (IPlugin)Activator.CreateInstance(pluginType);
            }
            catch (Exception ex)
            {
                throw new PluginInstantiationException(
                    $"Failed to create instance of {pluginType.FullName}", ex);
            }
        }
        
        private async Task InitializePluginAsync(IPlugin plugin, IPluginContext context)
        {
            if (plugin is IAsyncPlugin asyncPlugin)
            {
                await asyncPlugin.InitializeAsync(context);
            }
            else
            {
                plugin.Initialize(context);
            }
        }
        
        private void RegisterPluginUI(IPlugin plugin, string pluginId)
        {
            if (plugin is IUIPlugin uiPlugin)
            {
                _uiManager.RegisterPluginUI(pluginId, uiPlugin);
            }
        }
        
        private void RegisterPluginCommands(IPlugin plugin, string pluginId)
        {
            if (plugin is ICommandPlugin commandPlugin)
            {
                foreach (var command in commandPlugin.Commands)
                {
                    _commandManager.RegisterCommand(pluginId, command);
                }
            }
        }
        
        public async Task StartPluginAsync(string pluginId)
        {
            if (!_plugins.TryGetValue(pluginId, out var context))
                throw new PluginNotFoundException(pluginId);
            
            if (context.Status != PluginStatus.Loaded && 
                context.Status != PluginStatus.Stopped)
                throw new InvalidPluginStateException(
                    $"Cannot start plugin in {context.Status} state");
            
            _logger.Info($"Starting plugin: {context.PluginInfo.Name}");
            
            try
            {
                context.Status = PluginStatus.Starting;
                
                if (context.Plugin is IAsyncPlugin asyncPlugin)
                {
                    await asyncPlugin.StartAsync();
                }
                else
                {
                    context.Plugin.Start();
                }
                
                context.Status = PluginStatus.Running;
                context.StartTime = DateTime.UtcNow;
                
                _logger.Info($"Plugin {context.PluginInfo.Name} started successfully");
                
                await _eventAggregator.PublishAsync(new PluginStartedEvent
                {
                    PluginId = pluginId,
                    PluginName = context.PluginInfo.Name
                });
            }
            catch (Exception ex)
            {
                context.Status = PluginStatus.Error;
                context.LastError = ex;
                
                _logger.Error($"Failed to start plugin {pluginId}: {ex}");
                throw new PluginStartException($"Failed to start plugin {pluginId}", ex);
            }
        }
        
        public async Task StopPluginAsync(string pluginId)
        {
            if (!_plugins.TryGetValue(pluginId, out var context))
                return;
            
            if (context.Status != PluginStatus.Running)
                return;
            
            _logger.Info($"Stopping plugin: {context.PluginInfo.Name}");
            
            try
            {
                context.Status = PluginStatus.Stopping;
                
                // 检查是否有依赖于此插件的插件
                var dependents = _dependencyResolver.GetDependents(pluginId)
                    .Where(depId => _plugins.ContainsKey(depId) && 
                                  _plugins[depId].Status == PluginStatus.Running)
                    .ToList();
                
                if (dependents.Count > 0)
                {
                    _logger.Warning($"Plugin {pluginId} has running dependents: " +
                                   $"{string.Join(", ", dependents)}");
                }
                
                if (context.Plugin is IAsyncPlugin asyncPlugin)
                {
                    await asyncPlugin.StopAsync();
                }
                else
                {
                    context.Plugin.Stop();
                }
                
                context.Status = PluginStatus.Stopped;
                context.StopTime = DateTime.UtcNow;
                
                _monitor.StopMonitoring(pluginId);
                
                _logger.Info($"Plugin {context.PluginInfo.Name} stopped successfully");
                
                await _eventAggregator.PublishAsync(new PluginStoppedEvent
                {
                    PluginId = pluginId,
                    PluginName = context.PluginInfo.Name
                });
            }
            catch (Exception ex)
            {
                context.Status = PluginStatus.Error;
                context.LastError = ex;
                
                _logger.Error($"Error stopping plugin {pluginId}: {ex}");
            }
        }
        
        public async Task UnloadPluginAsync(string pluginId)
        {
            if (!_plugins.TryGetValue(pluginId, out var context))
                return;
            
            // 先停止插件
            if (context.Status == PluginStatus.Running)
            {
                await StopPluginAsync(pluginId);
            }
            
            _logger.Info($"Unloading plugin: {context.PluginInfo.Name}");
            
            try
            {
                context.Status = PluginStatus.Unloading;
                
                // 清理UI注册
                _uiManager.UnregisterPluginUI(pluginId);
                
                // 清理命令注册
                _commandManager.UnregisterPluginCommands(pluginId);
                
                // 释放插件资源
                context.Plugin?.Dispose();
                
                // 清理上下文
                context.PluginHostContext?.Dispose();
                
                lock (_lock)
                {
                    _plugins.Remove(pluginId);
                }
                
                // 卸载程序集(如果支持)
                if (_loader is IAssemblyUnloader unloader)
                {
                    await unloader.UnloadAssemblyAsync(context.PluginInfo.AssemblyPath);
                }
                
                _logger.Info($"Plugin {context.PluginInfo.Name} unloaded successfully");
                
                await _eventAggregator.PublishAsync(new PluginUnloadedEvent
                {
                    PluginId = pluginId,
                    PluginName = context.PluginInfo.Name
                });
            }
            catch (Exception ex)
            {
                _logger.Error($"Error unloading plugin {pluginId}: {ex}");
                throw;
            }
        }
        
        public async Task StartAllPluginsAsync()
        {
            var loadOrder = _dependencyResolver.GetLoadOrder();
            
            foreach (var pluginId in loadOrder)
            {
                if (_plugins.TryGetValue(pluginId, out var context) &&
                    context.Status == PluginStatus.Loaded)
                {
                    await StartPluginAsync(pluginId);
                }
            }
        }
        
        public async Task StopAllPluginsAsync()
        {
            var stopOrder = _dependencyResolver.GetStopOrder();
            
            foreach (var pluginId in stopOrder)
            {
                await StopPluginAsync(pluginId);
            }
        }
        
        public IReadOnlyDictionary<string, PluginInfo> GetInstalledPlugins()
        {
            return new ReadOnlyDictionary<string, PluginInfo>(_pluginInfos);
        }
        
        public IReadOnlyDictionary<string, PluginInfo> GetLoadedPlugins()
        {
            var loadedInfos = _plugins.ToDictionary(
                kv => kv.Key,
                kv => kv.Value.PluginInfo);
            
            return new ReadOnlyDictionary<string, PluginInfo>(loadedInfos);
        }
        
        public PluginStatus GetPluginStatus(string pluginId)
        {
            return _plugins.TryGetValue(pluginId, out var context) 
                ? context.Status 
                : PluginStatus.NotLoaded;
        }
        
        public PluginDiagnostics GetPluginDiagnostics(string pluginId)
        {
            if (!_plugins.TryGetValue(pluginId, out var context))
                return null;
            
            return new PluginDiagnostics
            {
                PluginId = pluginId,
                Status = context.Status,
                LoadTime = context.LoadTime,
                StartTime = context.StartTime,
                StopTime = context.StopTime,
                LastError = context.LastError?.Message,
                PerformanceMetrics = _monitor.GetMetrics(pluginId),
                MemoryUsage = _monitor.GetMemoryUsage(pluginId)
            };
        }
        
        public void Dispose()
        {
            StopAllPluginsAsync().Wait(TimeSpan.FromSeconds(30));
            
            foreach (var context in _plugins.Values)
            {
                try
                {
                    context.Plugin?.Dispose();
                    context.PluginHostContext?.Dispose();
                }
                catch (Exception ex)
                {
                    _logger.Error($"Error disposing plugin {context.PluginInfo.Id}: {ex}");
                }
            }
            
            _plugins.Clear();
            _scheduler.Dispose();
            _monitor.Dispose();
        }
        
        private class PluginContext
        {
            public PluginInfo PluginInfo { get; set; }
            public IPlugin Plugin { get; set; }
            public IPluginContext PluginHostContext { get; set; }
            public PluginStatus Status { get; set; }
            public DateTime LoadTime { get; set; }
            public DateTime? StartTime { get; set; }
            public DateTime? StopTime { get; set; }
            public Exception LastError { get; set; }
        }
    }
}

应用案例:可扩展的日志系统

csharp 复制代码
// 可扩展的日志系统插件架构
namespace ExtensibleLoggingSystem
{
    // 日志级别
    public enum LogLevel
    {
        Trace,
        Debug,
        Information,
        Warning,
        Error,
        Critical
    }
    
    // 日志记录接口
    public interface ILogRecord
    {
        DateTime Timestamp { get; }
        LogLevel Level { get; }
        string Message { get; }
        string Category { get; }
        Exception Exception { get; }
        Dictionary<string, object> Properties { get; }
    }
    
    // 日志接收器接口
    public interface ILogSink : IPlugin
    {
        string SinkType { get; }
        bool IsEnabled { get; set; }
        LogLevel MinimumLevel { get; set; }
        
        Task WriteAsync(ILogRecord record);
        Task FlushAsync();
    }
    
    // 日志格式化器接口
    public interface ILogFormatter : IPlugin
    {
        string Format { get; }
        
        string FormatRecord(ILogRecord record);
    }
    
    // 日志过滤器接口
    public interface ILogFilter : IPlugin
    {
        bool ShouldLog(ILogRecord record);
    }
    
    // 日志上下文提供器接口
    public interface ILogContextProvider : IPlugin
    {
        Dictionary<string, object> GetContextProperties();
    }
    
    // 可扩展的日志管理器
    public class ExtensibleLogger : IDisposable
    {
        private readonly List<ILogSink> _sinks = new List<ILogSink>();
        private readonly List<ILogFormatter> _formatters = new List<ILogFormatter>();
        private readonly List<ILogFilter> _filters = new List<ILogFilter>();
        private readonly List<ILogContextProvider> _contextProviders = new List<ILogContextProvider>();
        private readonly ConcurrentQueue<LogRecord> _logQueue = new ConcurrentQueue<LogRecord>();
        private readonly CancellationTokenSource _cts = new CancellationTokenSource();
        private Task _processingTask;
        
        public ExtensibleLogger(IPluginManager pluginManager)
        {
            // 从插件管理器获取所有日志相关插件
            var plugins = pluginManager.GetLoadedPlugins();
            
            foreach (var plugin in plugins.Values)
            {
                if (plugin.Instance is ILogSink sink)
                {
                    _sinks.Add(sink);
                }
                else if (plugin.Instance is ILogFormatter formatter)
                {
                    _formatters.Add(formatter);
                }
                else if (plugin.Instance is ILogFilter filter)
                {
                    _filters.Add(filter);
                }
                else if (plugin.Instance is ILogContextProvider provider)
                {
                    _contextProviders.Add(provider);
                }
            }
            
            // 启动日志处理任务
            _processingTask = Task.Run(ProcessLogQueueAsync);
        }
        
        public void Log(LogLevel level, string message, string category = null, 
                       Exception exception = null, 
                       Dictionary<string, object> properties = null)
        {
            var record = new LogRecord
            {
                Timestamp = DateTime.UtcNow,
                Level = level,
                Message = message,
                Category = category,
                Exception = exception,
                Properties = MergeProperties(properties)
            };
            
            _logQueue.Enqueue(record);
        }
        
        private Dictionary<string, object> MergeProperties(Dictionary<string, object> properties)
        {
            var result = new Dictionary<string, object>();
            
            // 添加上下文属性
            foreach (var provider in _contextProviders)
            {
                var contextProps = provider.GetContextProperties();
                if (contextProps != null)
                {
                    foreach (var kvp in contextProps)
                    {
                        result[kvp.Key] = kvp.Value;
                    }
                }
            }
            
            // 添加特定日志属性
            if (properties != null)
            {
                foreach (var kvp in properties)
                {
                    result[kvp.Key] = kvp.Value;
                }
            }
            
            return result;
        }
        
        private async Task ProcessLogQueueAsync()
        {
            while (!_cts.IsCancellationRequested)
            {
                try
                {
                    if (_logQueue.TryDequeue(out var record))
                    {
                        // 应用过滤器
                        if (!ShouldLog(record))
                            continue;
                        
                        // 格式化记录(如果需要)
                        var formattedRecord = FormatRecord(record);
                        
                        // 发送到所有启用的接收器
                        var tasks = new List<Task>();
                        foreach (var sink in _sinks.Where(s => s.IsEnabled && 
                                                             s.MinimumLevel <= record.Level))
                        {
                            tasks.Add(sink.WriteAsync(formattedRecord));
                        }
                        
                        await Task.WhenAll(tasks);
                    }
                    else
                    {
                        await Task.Delay(10, _cts.Token);
                    }
                }
                catch (Exception ex)
                {
                    // 日志系统本身的错误处理
                    Console.Error.WriteLine($"Log system error: {ex.Message}");
                }
            }
        }
        
        private bool ShouldLog(ILogRecord record)
        {
            foreach (var filter in _filters)
            {
                if (!filter.ShouldLog(record))
                    return false;
            }
            return true;
        }
        
        private ILogRecord FormatRecord(ILogRecord record)
        {
            // 如果有特定的格式化器,使用它们
            foreach (var formatter in _formatters)
            {
                // 可以根据记录属性选择格式化器
                if (record.Properties.TryGetValue("Format", out var format) &&
                    format?.ToString() == formatter.Format)
                {
                    return new FormattedLogRecord(record, formatter.FormatRecord(record));
                }
            }
            
            return record;
        }
        
        public async Task FlushAsync()
        {
            var tasks = _sinks.Select(s => s.FlushAsync()).ToList();
            await Task.WhenAll(tasks);
        }
        
        public void Dispose()
        {
            _cts.Cancel();
            _processingTask?.Wait(TimeSpan.FromSeconds(5));
            _processingTask?.Dispose();
            _cts.Dispose();
        }
        
        // 便利方法
        public void LogInformation(string message, string category = null)
            => Log(LogLevel.Information, message, category);
        
        public void LogWarning(string message, string category = null, Exception ex = null)
            => Log(LogLevel.Warning, message, category, ex);
        
        public void LogError(string message, string category = null, Exception ex = null)
            => Log(LogLevel.Error, message, category, ex);
        
        public void LogDebug(string message, string category = null)
            => Log(LogLevel.Debug, message, category);
    }
    
    // 具体插件实现示例
    [PluginMetadata(
        id: "com.example.logging.console",
        name: "Console Log Sink",
        version: "1.0.0",
        description: "Outputs logs to console",
        author: "Example Corp",
        Tags = new[] { "logging", "console" }
    )]
    public class ConsoleLogSink : ILogSink
    {
        public string SinkType => "Console";
        public bool IsEnabled { get; set; } = true;
        public LogLevel MinimumLevel { get; set; } = LogLevel.Information;
        
        private readonly object _lock = new object();
        
        public Task WriteAsync(ILogRecord record)
        {
            return Task.Run(() =>
            {
                lock (_lock)
                {
                    var color = GetColorForLevel(record.Level);
                    var originalColor = Console.ForegroundColor;
                    
                    Console.ForegroundColor = color;
                    Console.WriteLine($"[{record.Timestamp:HH:mm:ss}] [{record.Level}] {record.Message}");
                    
                    if (record.Exception != null)
                    {
                        Console.WriteLine($"Exception: {record.Exception}");
                    }
                    
                    Console.ForegroundColor = originalColor;
                }
            });
        }
        
        private ConsoleColor GetColorForLevel(LogLevel level)
        {
            return level switch
            {
                LogLevel.Trace => ConsoleColor.Gray,
                LogLevel.Debug => ConsoleColor.White,
                LogLevel.Information => ConsoleColor.Green,
                LogLevel.Warning => ConsoleColor.Yellow,
                LogLevel.Error => ConsoleColor.Red,
                LogLevel.Critical => ConsoleColor.DarkRed,
                _ => ConsoleColor.White
            };
        }
        
        public Task FlushAsync() => Task.CompletedTask;
        
        // IPlugin 实现
        public string Id => "com.example.logging.console";
        public string Name => "Console Log Sink";
        public Version Version => new Version(1, 0, 0);
        public string Description => "Outputs logs to console";
        public string Author => "Example Corp";
        public IPluginConfiguration Configuration { get; private set; }
        
        public void Initialize(IPluginContext context)
        {
            Configuration = context.ConfigurationManager.GetPluginConfiguration(Id);
            Configuration.Load();
            
            IsEnabled = Configuration.GetSetting("enabled", true);
            MinimumLevel = Configuration.GetSetting("minLevel", LogLevel.Information);
        }
        
        public void Start() { }
        public void Stop() { }
        public PluginStatus GetStatus() => PluginStatus.Running;
        public void Dispose() { }
    }
    
    [PluginMetadata(
        id: "com.example.logging.file",
        name: "File Log Sink",
        version: "1.0.0",
        description: "Writes logs to file",
        author: "Example Corp",
        Tags = new[] { "logging", "file" }
    )]
    public class FileLogSink : ILogSink
    {
        public string SinkType => "File";
        public bool IsEnabled { get; set; } = true;
        public LogLevel MinimumLevel { get; set; } = LogLevel.Information;
        
        private StreamWriter _writer;
        private readonly object _lock = new object();
        private string _logDirectory;
        private string _currentLogFile;
        private Timer _rolloverTimer;
        
        public async Task WriteAsync(ILogRecord record)
        {
            var logLine = $"[{record.Timestamp:yyyy-MM-dd HH:mm:ss.fff}] " +
                         $"[{record.Level}] " +
                         $"[{record.Category}] " +
                         $"{record.Message}";
            
            if (record.Exception != null)
            {
                logLine += $" | Exception: {record.Exception}";
            }
            
            lock (_lock)
            {
                if (_writer != null)
                {
                    _writer.WriteLine(logLine);
                }
            }
            
            await Task.CompletedTask;
        }
        
        public async Task FlushAsync()
        {
            lock (_lock)
            {
                _writer?.Flush();
            }
            await Task.CompletedTask;
        }
        
        // IPlugin 实现
        public string Id => "com.example.logging.file";
        public string Name => "File Log Sink";
        public Version Version => new Version(1, 0, 0);
        public string Description => "Writes logs to file";
        public string Author => "Example Corp";
        public IPluginConfiguration Configuration { get; private set; }
        
        public void Initialize(IPluginContext context)
        {
            Configuration = context.ConfigurationManager.GetPluginConfiguration(Id);
            Configuration.Load();
            
            IsEnabled = Configuration.GetSetting("enabled", true);
            MinimumLevel = Configuration.GetSetting("minLevel", LogLevel.Information);
            _logDirectory = Configuration.GetSetting("logDirectory", 
                Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs"));
            
            Directory.CreateDirectory(_logDirectory);
            
            InitializeLogFile();
            ScheduleRollover();
        }
        
        private void InitializeLogFile()
        {
            var fileName = $"log_{DateTime.Now:yyyyMMdd_HHmmss}.txt";
            _currentLogFile = Path.Combine(_logDirectory, fileName);
            
            lock (_lock)
            {
                _writer?.Dispose();
                _writer = new StreamWriter(_currentLogFile, append: true)
                {
                    AutoFlush = true
                };
            }
        }
        
        private void ScheduleRollover()
        {
            var rolloverInterval = Configuration.GetSetting("rolloverInterval", "daily");
            
            TimeSpan interval;
            switch (rolloverInterval.ToLower())
            {
                case "hourly":
                    interval = TimeSpan.FromHours(1);
                    break;
                case "daily":
                    interval = TimeSpan.FromDays(1);
                    break;
                case "weekly":
                    interval = TimeSpan.FromDays(7);
                    break;
                default:
                    interval = TimeSpan.FromDays(1);
                    break;
            }
            
            _rolloverTimer = new Timer(RolloverLogFile, null, interval, interval);
        }
        
        private void RolloverLogFile(object state)
        {
            InitializeLogFile();
        }
        
        public void Start() { }
        
        public void Stop()
        {
            _rolloverTimer?.Dispose();
            
            lock (_lock)
            {
                _writer?.Dispose();
                _writer = null;
            }
        }
        
        public PluginStatus GetStatus() => PluginStatus.Running;
        
        public void Dispose()
        {
            Stop();
        }
    }
    
    [PluginMetadata(
        id: "com.example.logging.json",
        name: "JSON Log Formatter",
        version: "1.0.0",
        description: "Formats logs as JSON",
        author: "Example Corp",
        Tags = new[] { "logging", "formatter", "json" }
    )]
    public class JsonLogFormatter : ILogFormatter
    {
        public string Format => "JSON";
        
        public string FormatRecord(ILogRecord record)
        {
            var logObject = new
            {
                timestamp = record.Timestamp,
                level = record.Level.ToString(),
                category = record.Category,
                message = record.Message,
                exception = record.Exception?.ToString(),
                properties = record.Properties
            };
            
            return JsonConvert.SerializeObject(logObject, Formatting.Indented);
        }
        
        // IPlugin 实现
        public string Id => "com.example.logging.json";
        public string Name => "JSON Log Formatter";
        public Version Version => new Version(1, 0, 0);
        public string Description => "Formats logs as JSON";
        public string Author => "Example Corp";
        public IPluginConfiguration Configuration { get; private set; }
        
        public void Initialize(IPluginContext context)
        {
            Configuration = context.ConfigurationManager.GetPluginConfiguration(Id);
        }
        
        public void Start() { }
        public void Stop() { }
        public PluginStatus GetStatus() => PluginStatus.Running;
        public void Dispose() { }
    }
    
    [PluginMetadata(
        id: "com.example.logging.filter",
        name: "Category Log Filter",
        version: "1.0.0",
        description: "Filters logs by category",
        author: "Example Corp",
        Tags = new[] { "logging", "filter" }
    )]
    public class CategoryLogFilter : ILogFilter
    {
        private HashSet<string> _excludedCategories = new HashSet<string>();
        private HashSet<string> _includedCategories = new HashSet<string>();
        
        public bool ShouldLog(ILogRecord record)
        {
            if (record.Category == null)
                return true;
            
            // 如果在排除列表中,则过滤掉
            if (_excludedCategories.Contains(record.Category))
                return false;
            
            // 如果指定了包含列表,则只记录包含的类别
            if (_includedCategories.Count > 0 && 
                !_includedCategories.Contains(record.Category))
                return false;
            
            return true;
        }
        
        // IPlugin 实现
        public string Id => "com.example.logging.filter";
        public string Name => "Category Log Filter";
        public Version Version => new Version(1, 0, 0);
        public string Description => "Filters logs by category";
        public string Author => "Example Corp";
        public IPluginConfiguration Configuration { get; private set; }
        
        public void Initialize(IPluginContext context)
        {
            Configuration = context.ConfigurationManager.GetPluginConfiguration(Id);
            Configuration.Load();
            
            var excluded = Configuration.GetSetting<string[]>("excludedCategories", 
                Array.Empty<string>());
            var included = Configuration.GetSetting<string[]>("includedCategories", 
                Array.Empty<string>());
            
            _excludedCategories = new HashSet<string>(excluded, StringComparer.OrdinalIgnoreCase);
            _includedCategories = new HashSet<string>(included, StringComparer.OrdinalIgnoreCase);
        }
        
        public void Start() { }
        public void Stop() { }
        public PluginStatus GetStatus() => PluginStatus.Running;
        public void Dispose() { }
    }
}

⚙️ 实践篇:C++ 下的插件式开发

1. 定义插件契约

cpp 复制代码
// plugin_framework.h - C++插件框架头文件
#pragma once

#include <memory>
#include <string>
#include <vector>
#include <functional>
#include <unordered_map>
#include <chrono>

#ifdef _WIN32
    #ifdef PLUGIN_EXPORTS
        #define PLUGIN_API __declspec(dllexport)
    #else
        #define PLUGIN_API __declspec(dllimport)
    #endif
#else
    #define PLUGIN_API __attribute__((visibility("default")))
#endif

namespace PluginFramework
{
    // 插件版本
    struct Version
    {
        int major;
        int minor;
        int patch;
        
        std::string toString() const
        {
            return std::to_string(major) + "." + 
                   std::to_string(minor) + "." + 
                   std::to_string(patch);
        }
        
        bool operator<(const Version& other) const
        {
            if (major != other.major) return major < other.major;
            if (minor != other.minor) return minor < other.minor;
            return patch < other.patch;
        }
        
        bool operator>=(const Version& other) const
        {
            return !(*this < other);
        }
    };
    
    // 插件状态
    enum class PluginStatus
    {
        NotLoaded,
        Loaded,
        Initializing,
        Initialized,
        Starting,
        Running,
        Stopping,
        Stopped,
        Error,
        Unloaded
    };
    
    // 插件信息
    struct PluginInfo
    {
        std::string id;
        std::string name;
        Version version;
        std::string description;
        std::string author;
        std::string website;
        std::string license;
        std::vector<std::string> dependencies;
        std::vector<std::string> tags;
    };
    
    // 插件上下文
    class IPluginContext
    {
    public:
        virtual ~IPluginContext() = default;
        
        virtual std::string getHostName() const = 0;
        virtual Version getHostVersion() const = 0;
        
        virtual void logInfo(const std::string& message) = 0;
        virtual void logWarning(const std::string& message) = 0;
        virtual void logError(const std::string& message) = 0;
        
        virtual void* getService(const std::string& serviceName) = 0;
        virtual bool hasService(const std::string& serviceName) const = 0;
        
        virtual std::shared_ptr<void> getSharedService(const std::string& serviceName) = 0;
    };
    
    // 插件接口
    class IPlugin
    {
    public:
        virtual ~IPlugin() = default;
        
        virtual PluginInfo getPluginInfo() const = 0;
        virtual PluginStatus getStatus() const = 0;
        
        virtual bool initialize(std::shared_ptr<IPluginContext> context) = 0;
        virtual bool start() = 0;
        virtual bool stop() = 0;
        virtual bool shutdown() = 0;
        
        virtual std::string getLastError() const = 0;
    };
    
    // 配置接口
    class IConfiguration
    {
    public:
        virtual ~IConfiguration() = default;
        
        virtual bool load(const std::string& filePath) = 0;
        virtual bool save(const std::string& filePath) = 0;
        
        template<typename T>
        T getValue(const std::string& key, const T& defaultValue = T()) const;
        
        template<typename T>
        void setValue(const std::string& key, const T& value);
        
        virtual bool hasKey(const std::string& key) const = 0;
        virtual std::vector<std::string> getKeys() const = 0;
    };
    
    // 事件系统
    class IEvent
    {
    public:
        virtual ~IEvent() = default;
        virtual std::string getType() const = 0;
        virtual std::chrono::system_clock::time_point getTimestamp() const = 0;
        virtual const void* getSource() const = 0;
    };
    
    class IEventBus
    {
    public:
        virtual ~IEventBus() = default;
        
        using EventHandler = std::function<void(const std::shared_ptr<IEvent>&)>;
        
        virtual void subscribe(const std::string& eventType, EventHandler handler) = 0;
        virtual void unsubscribe(const std::string& eventType, EventHandler handler) = 0;
        virtual void publish(const std::shared_ptr<IEvent>& event) = 0;
        
        virtual size_t getSubscriberCount(const std::string& eventType) const = 0;
    };
    
    // 插件工厂函数类型
    typedef IPlugin* (*CreatePluginFunc)();
    typedef void (*DestroyPluginFunc)(IPlugin*);
    
    // 插件导出宏
    #define EXPORT_PLUGIN(PluginClass) \
        extern "C" { \
            PLUGIN_API PluginFramework::IPlugin* createPlugin() { \
                return new PluginClass(); \
            } \
            PLUGIN_API void destroyPlugin(PluginFramework::IPlugin* plugin) { \
                if (plugin) { \
                    plugin->shutdown(); \
                    delete plugin; \
                } \
            } \
            PLUGIN_API const char* getPluginName() { \
                return PluginClass::staticGetPluginInfo().name.c_str(); \
            } \
            PLUGIN_API const char* getPluginVersion() { \
                return PluginClass::staticGetPluginInfo().version.toString().c_str(); \
            } \
        }
}

2. 实现一个具体插件

cpp 复制代码
// image_processor_plugin.h
#pragma once

#include "plugin_framework.h"
#include <opencv2/opencv.hpp>
#include <vector>
#include <memory>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <thread>

namespace ImageProcessing
{
    // 图像处理参数
    struct ImageProcessParams
    {
        std::string inputPath;
        std::string outputPath;
        std::vector<std::string> filters;
        int quality = 95;
        bool overwrite = false;
    };
    
    // 处理结果
    struct ProcessResult
    {
        bool success;
        std::string message;
        std::string outputPath;
        double processingTime; // 秒
    };
    
    // 图像处理器接口
    class IImageProcessor
    {
    public:
        virtual ~IImageProcessor() = default;
        
        virtual ProcessResult processImage(const ImageProcessParams& params) = 0;
        virtual std::vector<std::string> getAvailableFilters() const = 0;
        virtual bool hasFilter(const std::string& filterName) const = 0;
    };
    
    // 图像处理器插件
    class ImageProcessorPlugin : public PluginFramework::IPlugin,
                                 public IImageProcessor
    {
    public:
        static PluginFramework::PluginInfo staticGetPluginInfo()
        {
            PluginFramework::PluginInfo info;
            info.id = "com.example.imageprocessor";
            info.name = "Image Processor Plugin";
            info.version = {1, 0, 0};
            info.description = "Advanced image processing capabilities";
            info.author = "Example Corp";
            info.website = "https://example.com";
            info.license = "MIT";
            info.dependencies = {"com.example.core"};
            info.tags = {"image", "processing", "opencv"};
            return info;
        }
        
        // IPlugin 实现
        PluginFramework::PluginInfo getPluginInfo() const override
        {
            return staticGetPluginInfo();
        }
        
        PluginFramework::PluginStatus getStatus() const override
        {
            std::lock_guard<std::mutex> lock(mutex_);
            return status_;
        }
        
        bool initialize(std::shared_ptr<PluginFramework::IPluginContext> context) override
        {
            std::lock_guard<std::mutex> lock(mutex_);
            
            if (status_ != PluginFramework::PluginStatus::NotLoaded)
            {
                lastError_ = "Plugin already initialized";
                return false;
            }
            
            try
            {
                context_ = context;
                status_ = PluginFramework::PluginStatus::Initializing;
                
                // 初始化配置
                config_ = loadConfiguration();
                
                // 初始化OpenCV
                if (!initializeOpenCV())
                {
                    status_ = PluginFramework::PluginStatus::Error;
                    lastError_ = "Failed to initialize OpenCV";
                    return false;
                }
                
                // 注册事件处理器
                if (auto eventBus = getEventBus())
                {
                    eventBus->subscribe("ImageLoadEvent", 
                        [this](const std::shared_ptr<PluginFramework::IEvent>& event) {
                            onImageLoaded(event);
                        });
                }
                
                // 启动处理线程
                processingThread_ = std::thread(&ImageProcessorPlugin::processQueue, this);
                
                status_ = PluginFramework::PluginStatus::Initialized;
                context_->logInfo("ImageProcessorPlugin initialized successfully");
                return true;
            }
            catch (const std::exception& e)
            {
                status_ = PluginFramework::PluginStatus::Error;
                lastError_ = std::string("Initialization failed: ") + e.what();
                context_->logError(lastError_);
                return false;
            }
        }
        
        bool start() override
        {
            std::lock_guard<std::mutex> lock(mutex_);
            
            if (status_ != PluginFramework::PluginStatus::Initialized &&
                status_ != PluginFramework::PluginStatus::Stopped)
            {
                lastError_ = "Plugin not in correct state for starting";
                return false;
            }
            
            status_ = PluginFramework::PluginStatus::Running;
            context_->logInfo("ImageProcessorPlugin started");
            return true;
        }
        
        bool stop() override
        {
            std::lock_guard<std::mutex> lock(mutex_);
            
            if (status_ != PluginFramework::PluginStatus::Running)
                return true;
            
            status_ = PluginFramework::PluginStatus::Stopping;
            
            // 通知处理线程停止
            {
                std::lock_guard<std::mutex> queueLock(queueMutex_);
                stopProcessing_ = true;
                queueCondition_.notify_all();
            }
            
            // 等待处理线程结束
            if (processingThread_.joinable())
            {
                processingThread_.join();
            }
            
            status_ = PluginFramework::PluginStatus::Stopped;
            context_->logInfo("ImageProcessorPlugin stopped");
            return true;
        }
        
        bool shutdown() override
        {
            stop();
            
            std::lock_guard<std::mutex> lock(mutex_);
            status_ = PluginFramework::PluginStatus::Unloaded;
            
            // 清理资源
            if (auto eventBus = getEventBus())
            {
                // 需要保存事件处理器引用以便取消订阅
            }
            
            context_.reset();
            config_.reset();
            
            return true;
        }
        
        std::string getLastError() const override
        {
            std::lock_guard<std::mutex> lock(mutex_);
            return lastError_;
        }
        
        // IImageProcessor 实现
        ProcessResult processImage(const ImageProcessParams& params) override
        {
            if (getStatus() != PluginFramework::PluginStatus::Running)
            {
                return {false, "Plugin not running", "", 0.0};
            }
            
            auto startTime = std::chrono::high_resolution_clock::now();
            
            try
            {
                // 读取图像
                cv::Mat image = cv::imread(params.inputPath, cv::IMREAD_COLOR);
                if (image.empty())
                {
                    return {false, "Failed to load image: " + params.inputPath, "", 0.0};
                }
                
                // 应用滤镜
                cv::Mat processed = image.clone();
                for (const auto& filter : params.filters)
                {
                    processed = applyFilter(processed, filter);
                }
                
                // 保存图像
                std::vector<int> compressionParams;
                compressionParams.push_back(cv::IMWRITE_JPEG_QUALITY);
                compressionParams.push_back(params.quality);
                
                if (!cv::imwrite(params.outputPath, processed, compressionParams))
                {
                    return {false, "Failed to save image: " + params.outputPath, "", 0.0};
                }
                
                auto endTime = std::chrono::high_resolution_clock::now();
                double processingTime = std::chrono::duration<double>(endTime - startTime).count();
                
                return {true, "Image processed successfully", params.outputPath, processingTime};
            }
            catch (const cv::Exception& e)
            {
                return {false, std::string("OpenCV error: ") + e.what(), "", 0.0};
            }
            catch (const std::exception& e)
            {
                return {false, std::string("Error: ") + e.what(), "", 0.0};
            }
        }
        
        std::vector<std::string> getAvailableFilters() const override
        {
            return {
                "grayscale",
                "blur",
                "sharpen",
                "edge_detect",
                "emboss",
                "sepia",
                "invert",
                "brightness",
                "contrast"
            };
        }
        
        bool hasFilter(const std::string& filterName) const override
        {
            auto filters = getAvailableFilters();
            return std::find(filters.begin(), filters.end(), filterName) != filters.end();
        }
        
        // 异步处理接口
        using ProcessCallback = std::function<void(const ProcessResult&)>;
        
        void processImageAsync(const ImageProcessParams& params, ProcessCallback callback)
        {
            std::lock_guard<std::mutex> lock(queueMutex_);
            processQueue_.push({params, callback});
            queueCondition_.notify_one();
        }
        
    private:
        struct ProcessTask
        {
            ImageProcessParams params;
            ProcessCallback callback;
        };
        
        mutable std::mutex mutex_;
        PluginFramework::PluginStatus status_ = PluginFramework::PluginStatus::NotLoaded;
        std::string lastError_;
        
        std::shared_ptr<PluginFramework::IPluginContext> context_;
        std::shared_ptr<PluginFramework::IConfiguration> config_;
        
        std::thread processingThread_;
        std::queue<ProcessTask> processQueue_;
        std::mutex queueMutex_;
        std::condition_variable queueCondition_;
        bool stopProcessing_ = false;
        
        std::shared_ptr<PluginFramework::IConfiguration> loadConfiguration()
        {
            // 从上下文获取配置管理器
            if (auto configManager = static_cast<PluginFramework::IConfigurationManager*>(
                context_->getService("ConfigurationManager")))
            {
                return configManager->getPluginConfiguration(getPluginInfo().id);
            }
            return nullptr;
        }
        
        std::shared_ptr<PluginFramework::IEventBus> getEventBus()
        {
            if (context_)
            {
                return std::static_pointer_cast<PluginFramework::IEventBus>(
                    context_->getSharedService("EventBus"));
            }
            return nullptr;
        }
        
        bool initializeOpenCV()
        {
            // 检查OpenCV版本
            if (CV_VERSION_MAJOR < 4)
            {
                context_->logWarning("OpenCV version < 4.0 may have limited features");
            }
            
            // 初始化OpenCV的并行处理
            cv::setNumThreads(std::thread::hardware_concurrency());
            
            context_->logInfo("OpenCV initialized: " + std::string(cv::getVersionString()));
            return true;
        }
        
        cv::Mat applyFilter(const cv::Mat& input, const std::string& filterName)
        {
            cv::Mat output;
            
            if (filterName == "grayscale")
            {
                cv::cvtColor(input, output, cv::COLOR_BGR2GRAY);
                cv::cvtColor(output, output, cv::COLOR_GRAY2BGR);
            }
            else if (filterName == "blur")
            {
                cv::GaussianBlur(input, output, cv::Size(5, 5), 0);
            }
            else if (filterName == "sharpen")
            {
                cv::Mat kernel = (cv::Mat_<float>(3, 3) <<
                    0, -1, 0,
                    -1, 5, -1,
                    0, -1, 0);
                cv::filter2D(input, output, -1, kernel);
            }
            else if (filterName == "edge_detect")
            {
                cv::Mat gray, edges;
                cv::cvtColor(input, gray, cv::COLOR_BGR2GRAY);
                cv::Canny(gray, edges, 100, 200);
                cv::cvtColor(edges, output, cv::COLOR_GRAY2BGR);
            }
            else if (filterName == "emboss")
            {
                cv::Mat kernel = (cv::Mat_<float>(3, 3) <<
                    -2, -1, 0,
                    -1, 1, 1,
                    0, 1, 2);
                cv::filter2D(input, output, -1, kernel);
                cv::add(output, cv::Scalar(128, 128, 128), output);
            }
            else if (filterName == "sepia")
            {
                cv::Mat kernel = (cv::Mat_<float>(3, 3) <<
                    0.272, 0.534, 0.131,
                    0.349, 0.686, 0.168,
                    0.393, 0.769, 0.189);
                cv::transform(input, output, kernel);
            }
            else if (filterName == "invert")
            {
                output = cv::Scalar(255, 255, 255) - input;
            }
            else if (filterName == "brightness")
            {
                double brightness = 1.2; // 从配置获取
                input.convertTo(output, -1, brightness, 0);
            }
            else if (filterName == "contrast")
            {
                double contrast = 1.5; // 从配置获取
                input.convertTo(output, -1, contrast, 0);
            }
            else
            {
                // 未知滤镜,返回原图
                output = input.clone();
            }
            
            return output;
        }
        
        void processQueue()
        {
            while (true)
            {
                ProcessTask task;
                
                {
                    std::unique_lock<std::mutex> lock(queueMutex_);
                    queueCondition_.wait(lock, [this]() {
                        return !processQueue_.empty() || stopProcessing_;
                    });
                    
                    if (stopProcessing_ && processQueue_.empty())
                    {
                        break;
                    }
                    
                    if (!processQueue_.empty())
                    {
                        task = std::move(processQueue_.front());
                        processQueue_.pop();
                    }
                }
                
                if (task.callback)
                {
                    ProcessResult result = processImage(task.params);
                    task.callback(result);
                }
            }
        }
        
        void onImageLoaded(const std::shared_ptr<PluginFramework::IEvent>& event)
        {
            // 自动处理加载的图像
            if (auto imageEvent = std::dynamic_pointer_cast<ImageLoadEvent>(event))
            {
                ImageProcessParams params;
                params.inputPath = imageEvent->getImagePath();
                params.outputPath = generateOutputPath(params.inputPath);
                params.filters = {"auto_contrast", "sharpen"};
                
                processImageAsync(params, [this](const ProcessResult& result) {
                    if (result.success)
                    {
                        context_->logInfo("Auto-processed image: " + result.outputPath);
                        
                        // 发布处理完成事件
                        if (auto eventBus = getEventBus())
                        {
                            auto processedEvent = std::make_shared<ImageProcessedEvent>(
                                result.outputPath, getPluginInfo().name);
                            eventBus->publish(processedEvent);
                        }
                    }
                });
            }
        }
        
        std::string generateOutputPath(const std::string& inputPath)
        {
            std::string outputDir = config_ ? 
                config_->getValue<std::string>("outputDirectory", "/tmp/processed") :
                "/tmp/processed";
            
            // 确保目录存在
            std::filesystem::create_directories(outputDir);
            
            std::string filename = std::filesystem::path(inputPath).filename().string();
            std::string stem = std::filesystem::path(filename).stem().string();
            std::string extension = std::filesystem::path(filename).extension().string();
            
            return outputDir + "/" + stem + "_processed" + extension;
        }
    };
}

// 导出插件
EXPORT_PLUGIN(ImageProcessing::ImageProcessorPlugin)

3. 构建宿主程序(插件加载器)

cpp 复制代码
// plugin_host.cpp - C++插件宿主程序
#include "plugin_framework.h"
#include <iostream>
#include <filesystem>
#include <vector>
#include <memory>
#include <mutex>
#include <unordered_map>
#include <algorithm>
#include <dlfcn.h> // Linux/macOS
// Windows: #include <windows.h>

#ifdef _WIN32
    #include <windows.h>
    typedef HMODULE LibraryHandle;
    #define LIBRARY_EXT ".dll"
    #define LoadLibraryFunc LoadLibraryW
    #define GetProcAddressFunc GetProcAddress
    #define FreeLibraryFunc FreeLibrary
#else
    typedef void* LibraryHandle;
    #define LIBRARY_EXT ".so"
    #define LoadLibraryFunc dlopen
    #define GetProcAddressFunc dlsym
    #define FreeLibraryFunc dlclose
#endif

namespace PluginHost
{
    // 插件库包装器
    class PluginLibrary
    {
    public:
        PluginLibrary(const std::string& path)
            : libraryPath_(path), handle_(nullptr)
        {
        }
        
        ~PluginLibrary()
        {
            unload();
        }
        
        bool load()
        {
            if (handle_) return true;
            
#ifdef _WIN32
            std::wstring widePath = std::filesystem::path(libraryPath_).wstring();
            handle_ = LoadLibraryW(widePath.c_str());
#else
            handle_ = dlopen(libraryPath_.c_str(), RTLD_LAZY | RTLD_LOCAL);
#endif
            
            if (!handle_)
            {
                lastError_ = getLastError();
                return false;
            }
            
            // 获取插件工厂函数
            createFunc_ = reinterpret_cast<PluginFramework::CreatePluginFunc>(
                getSymbol("createPlugin"));
            destroyFunc_ = reinterpret_cast<PluginFramework::DestroyPluginFunc>(
                getSymbol("destroyPlugin"));
            getNameFunc_ = reinterpret_cast<const char*(*)()>(
                getSymbol("getPluginName"));
            getVersionFunc_ = reinterpret_cast<const char*(*)()>(
                getSymbol("getPluginVersion"));
            
            if (!createFunc_ || !destroyFunc_ || !getNameFunc_ || !getVersionFunc_)
            {
                lastError_ = "Missing required plugin export functions";
                unload();
                return false;
            }
            
            return true;
        }
        
        void unload()
        {
            if (handle_)
            {
                FreeLibraryFunc(handle_);
                handle_ = nullptr;
                createFunc_ = nullptr;
                destroyFunc_ = nullptr;
                getNameFunc_ = nullptr;
                getVersionFunc_ = nullptr;
            }
        }
        
        PluginFramework::IPlugin* createPlugin() const
        {
            return createFunc_ ? createFunc_() : nullptr;
        }
        
        void destroyPlugin(PluginFramework::IPlugin* plugin) const
        {
            if (destroyFunc_ && plugin)
            {
                destroyFunc_(plugin);
            }
        }
        
        std::string getPluginName() const
        {
            return getNameFunc_ ? getNameFunc_() : "";
        }
        
        std::string getPluginVersion() const
        {
            return getVersionFunc_ ? getVersionFunc_() : "";
        }
        
        bool isLoaded() const { return handle_ != nullptr; }
        std::string getPath() const { return libraryPath_; }
        std::string getLastError() const { return lastError_; }
        
    private:
        void* getSymbol(const char* name)
        {
#ifdef _WIN32
            return GetProcAddress(static_cast<HMODULE>(handle_), name);
#else
            return dlsym(handle_, name);
#endif
        }
        
        std::string getLastError()
        {
#ifdef _WIN32
            DWORD error = GetLastError();
            if (error == 0) return "";
            
            LPSTR buffer = nullptr;
            size_t size = FormatMessageA(
                FORMAT_MESSAGE_ALLOCATE_BUFFER | 
                FORMAT_MESSAGE_FROM_SYSTEM | 
                FORMAT_MESSAGE_IGNORE_INSERTS,
                NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                (LPSTR)&buffer, 0, NULL);
            
            std::string message(buffer, size);
            LocalFree(buffer);
            return message;
#else
            const char* error = dlerror();
            return error ? error : "";
#endif
        }
        
        std::string libraryPath_;
        LibraryHandle handle_;
        PluginFramework::CreatePluginFunc createFunc_ = nullptr;
        PluginFramework::DestroyPluginFunc destroyFunc_ = nullptr;
        const char*(*getNameFunc_)() = nullptr;
        const char*(*getVersionFunc_)() = nullptr;
        std::string lastError_;
    };
    
    // 插件管理器
    class PluginManager
    {
    public:
        struct PluginEntry
        {
            std::shared_ptr<PluginLibrary> library;
            std::shared_ptr<PluginFramework::IPlugin> plugin;
            PluginFramework::PluginInfo info;
            PluginFramework::PluginStatus status;
            std::chrono::system_clock::time_point loadTime;
            std::string lastError;
        };
        
        PluginManager(std::shared_ptr<PluginFramework::IPluginContext> hostContext)
            : hostContext_(hostContext)
        {
        }
        
        bool loadPlugin(const std::string& pluginPath)
        {
            std::lock_guard<std::mutex> lock(mutex_);
            
            // 检查是否已经加载
            for (const auto& entry : plugins_)
            {
                if (entry.second.library->getPath() == pluginPath)
                {
                    return true; // 已经加载
                }
            }
            
            auto library = std::make_shared<PluginLibrary>(pluginPath);
            if (!library->load())
            {
                std::cerr << "Failed to load plugin library: " 
                          << library->getLastError() << std::endl;
                return false;
            }
            
            // 创建插件实例
            auto plugin = std::shared_ptr<PluginFramework::IPlugin>(
                library->createPlugin(),
                [library](PluginFramework::IPlugin* p) {
                    if (p) library->destroyPlugin(p);
                });
            
            if (!plugin)
            {
                std::cerr << "Failed to create plugin instance" << std::endl;
                return false;
            }
            
            // 获取插件信息
            auto info = plugin->getPluginInfo();
            std::string libraryName = library->getPluginName();
            std::string libraryVersion = library->getPluginVersion();
            
            // 验证信息一致性
            if (info.name != libraryName || 
                info.version.toString() != libraryVersion)
            {
                std::cerr << "Plugin info mismatch between metadata and library exports" 
                          << std::endl;
                return false;
            }
            
            // 检查依赖
            if (!checkDependencies(info))
            {
                std::cerr << "Missing dependencies for plugin: " << info.name << std::endl;
                return false;
            }
            
            // 初始化插件
            if (!plugin->initialize(hostContext_))
            {
                std::cerr << "Failed to initialize plugin: " << info.name 
                          << ", error: " << plugin->getLastError() << std::endl;
                return false;
            }
            
            // 添加到管理器
            PluginEntry entry;
            entry.library = library;
            entry.plugin = plugin;
            entry.info = info;
            entry.status = PluginFramework::PluginStatus::Loaded;
            entry.loadTime = std::chrono::system_clock::now();
            
            plugins_[info.id] = entry;
            
            // 添加到依赖图
            dependencyGraph_[info.id] = info.dependencies;
            for (const auto& dep : info.dependencies)
            {
                reverseDependencyGraph_[dep].push_back(info.id);
            }
            
            std::cout << "Plugin loaded: " << info.name 
                      << " v" << info.version.toString() << std::endl;
            
            return true;
        }
        
        bool unloadPlugin(const std::string& pluginId)
        {
            std::lock_guard<std::mutex> lock(mutex_);
            
            auto it = plugins_.find(pluginId);
            if (it == plugins_.end())
            {
                return false;
            }
            
            // 检查是否有其他插件依赖于此插件
            auto reverseDeps = reverseDependencyGraph_.find(pluginId);
            if (reverseDeps != reverseDependencyGraph_.end() && 
                !reverseDeps->second.empty())
            {
                std::cerr << "Cannot unload plugin " << pluginId 
                          << ", it is depended on by: ";
                for (const auto& dep : reverseDeps->second)
                {
                    if (plugins_.find(dep) != plugins_.end())
                    {
                        std::cerr << dep << " ";
                    }
                }
                std::cerr << std::endl;
                return false;
            }
            
            // 停止插件
            if (it->second.status == PluginFramework::PluginStatus::Running)
            {
                it->second.plugin->stop();
            }
            
            // 关闭插件
            it->second.plugin->shutdown();
            
            // 从依赖图中移除
            dependencyGraph_.erase(pluginId);
            reverseDependencyGraph_.erase(pluginId);
            
            // 从其他插件的依赖中移除
            for (auto& pair : dependencyGraph_)
            {
                auto& deps = pair.second;
                deps.erase(std::remove(deps.begin(), deps.end(), pluginId), deps.end());
            }
            
            plugins_.erase(it);
            
            std::cout << "Plugin unloaded: " << pluginId << std::endl;
            return true;
        }
        
        bool startPlugin(const std::string& pluginId)
        {
            std::lock_guard<std::mutex> lock(mutex_);
            
            auto it = plugins_.find(pluginId);
            if (it == plugins_.end())
            {
                return false;
            }
            
            if (it->second.status != PluginFramework::PluginStatus::Loaded &&
                it->second.status != PluginFramework::PluginStatus::Stopped)
            {
                return false;
            }
            
            if (!it->second.plugin->start())
            {
                it->second.lastError = it->second.plugin->getLastError();
                return false;
            }
            
            it->second.status = PluginFramework::PluginStatus::Running;
            return true;
        }
        
        bool stopPlugin(const std::string& pluginId)
        {
            std::lock_guard<std::mutex> lock(mutex_);
            
            auto it = plugins_.find(pluginId);
            if (it == plugins_.end())
            {
                return false;
            }
            
            if (it->second.status != PluginFramework::PluginStatus::Running)
            {
                return true;
            }
            
            if (!it->second.plugin->stop())
            {
                it->second.lastError = it->second.plugin->getLastError();
                return false;
            }
            
            it->second.status = PluginFramework::PluginStatus::Stopped;
            return true;
        }
        
        void discoverPlugins(const std::string& directory)
        {
            namespace fs = std::filesystem;
            
            if (!fs::exists(directory) || !fs::is_directory(directory))
            {
                std::cerr << "Plugin directory does not exist: " << directory << std::endl;
                return;
            }
            
            std::lock_guard<std::mutex> lock(mutex_);
            
            for (const auto& entry : fs::directory_iterator(directory))
            {
                if (entry.is_regular_file() && 
                    entry.path().extension().string() == LIBRARY_EXT)
                {
                    try
                    {
                        // 尝试加载插件库获取基本信息(不初始化)
                        auto library = std::make_shared<PluginLibrary>(entry.path().string());
                        if (library->load())
                        {
                            auto plugin = library->createPlugin();
                            if (plugin)
                            {
                                auto info = plugin->getPluginInfo();
                                library->destroyPlugin(plugin);
                                
                                discoveredPlugins_[info.id] = {
                                    library, nullptr, info, 
                                    PluginFramework::PluginStatus::NotLoaded,
                                    std::chrono::system_clock::time_point(),
                                    ""
                                };
                                
                                std::cout << "Discovered plugin: " << info.name 
                                          << " (" << info.id << ")" << std::endl;
                            }
                            else
                            {
                                library->unload();
                            }
                        }
                    }
                    catch (const std::exception& e)
                    {
                        std::cerr << "Error discovering plugin " 
                                  << entry.path().string() << ": " << e.what() << std::endl;
                    }
                }
            }
        }
        
        std::vector<std::string> getLoadOrder() const
        {
            std::vector<std::string> order;
            std::unordered_set<std::string> visited;
            std::unordered_set<std::string> temp;
            
            for (const auto& pair : dependencyGraph_)
            {
                if (visited.find(pair.first) == visited.end())
                {
                    if (!topologicalSort(pair.first, visited, temp, order))
                    {
                        throw std::runtime_error("Circular dependency detected");
                    }
                }
            }
            
            std::reverse(order.begin(), order.end());
            return order;
        }
        
        void loadAllDiscovered()
        {
            auto order = getLoadOrder();
            for (const auto& pluginId : order)
            {
                auto it = discoveredPlugins_.find(pluginId);
                if (it != discoveredPlugins_.end())
                {
                    loadPlugin(it->second.library->getPath());
                }
            }
        }
        
        void startAll()
        {
            std::lock_guard<std::mutex> lock(mutex_);
            for (auto& pair : plugins_)
            {
                if (pair.second.status == PluginFramework::PluginStatus::Loaded)
                {
                    startPlugin(pair.first);
                }
            }
        }
        
        void stopAll()
        {
            std::lock_guard<std::mutex> lock(mutex_);
            
            // 按依赖逆序停止
            auto order = getLoadOrder();
            std::reverse(order.begin(), order.end());
            
            for (const auto& pluginId : order)
            {
                if (plugins_.find(pluginId) != plugins_.end())
                {
                    stopPlugin(pluginId);
                }
            }
        }
        
        std::vector<PluginFramework::PluginInfo> getLoadedPlugins() const
        {
            std::lock_guard<std::mutex> lock(mutex_);
            std::vector<PluginFramework::PluginInfo> result;
            
            for (const auto& pair : plugins_)
            {
                result.push_back(pair.second.info);
            }
            
            return result;
        }
        
        std::shared_ptr<PluginFramework::IPlugin> getPlugin(const std::string& pluginId) const
        {
            std::lock_guard<std::mutex> lock(mutex_);
            auto it = plugins_.find(pluginId);
            return it != plugins_.end() ? it->second.plugin : nullptr;
        }
        
    private:
        bool checkDependencies(const PluginFramework::PluginInfo& info)
        {
            for (const auto& dep : info.dependencies)
            {
                if (plugins_.find(dep) == plugins_.end() &&
                    discoveredPlugins_.find(dep) == discoveredPlugins_.end())
                {
                    return false;
                }
            }
            return true;
        }
        
        bool topologicalSort(
            const std::string& pluginId,
            std::unordered_set<std::string>& visited,
            std::unordered_set<std::string>& temp,
            std::vector<std::string>& order) const
        {
            if (temp.find(pluginId) != temp.end())
            {
                return false; // 循环依赖
            }
            
            if (visited.find(pluginId) != visited.end())
            {
                return true;
            }
            
            temp.insert(pluginId);
            
            auto it = dependencyGraph_.find(pluginId);
            if (it != dependencyGraph_.end())
            {
                for (const auto& dep : it->second)
                {
                    if (!topologicalSort(dep, visited, temp, order))
                    {
                        return false;
                    }
                }
            }
            
            temp.erase(pluginId);
            visited.insert(pluginId);
            order.push_back(pluginId);
            
            return true;
        }
        
        mutable std::mutex mutex_;
        std::shared_ptr<PluginFramework::IPluginContext> hostContext_;
        
        std::unordered_map<std::string, PluginEntry> plugins_;
        std::unordered_map<std::string, PluginEntry> discoveredPlugins_;
        
        std::unordered_map<std::string, std::vector<std::string>> dependencyGraph_;
        std::unordered_map<std::string, std::vector<std::string>> reverseDependencyGraph_;
    };
    
    // 宿主应用程序
    class HostApplication
    {
    public:
        HostApplication()
        {
            // 创建宿主上下文
            hostContext_ = createHostContext();
            
            // 创建插件管理器
            pluginManager_ = std::make_shared<PluginManager>(hostContext_);
            
            // 初始化事件总线等核心服务
            initializeCoreServices();
        }
        
        void run(const std::string& pluginDirectory)
        {
            std::cout << "Starting plugin host application..." << std::endl;
            
            // 发现插件
            pluginManager_->discoverPlugins(pluginDirectory);
            
            // 加载所有插件
            pluginManager_->loadAllDiscovered();
            
            // 启动所有插件
            pluginManager_->startAll();
            
            std::cout << "Plugin host is running. Press Enter to stop..." << std::endl;
            std::cin.get();
            
            // 停止所有插件
            pluginManager_->stopAll();
            
            std::cout << "Plugin host stopped." << std::endl;
        }
        
        std::shared_ptr<PluginFramework::IPlugin> getPlugin(const std::string& pluginId)
        {
            return pluginManager_->getPlugin(pluginId);
        }
        
    private:
        class HostContext : public PluginFramework::IPluginContext
        {
        public:
            std::string getHostName() const override
            {
                return "C++ Plugin Host";
            }
            
            PluginFramework::Version getHostVersion() const override
            {
                return {1, 0, 0};
            }
            
            void logInfo(const std::string& message) override
            {
                std::cout << "[INFO] " << message << std::endl;
            }
            
            void logWarning(const std::string& message) override
            {
                std::cout << "[WARN] " << message << std::endl;
            }
            
            void logError(const std::string& message) override
            {
                std::cerr << "[ERROR] " << message << std::endl;
            }
            
            void* getService(const std::string& serviceName) override
            {
                // 简单服务查找
                if (serviceName == "EventBus")
                {
                    return eventBus_.get();
                }
                else if (serviceName == "ConfigurationManager")
                {
                    return configManager_.get();
                }
                return nullptr;
            }
            
            bool hasService(const std::string& serviceName) const override
            {
                return serviceName == "EventBus" || serviceName == "ConfigurationManager";
            }
            
            std::shared_ptr<void> getSharedService(const std::string& serviceName) override
            {
                if (serviceName == "EventBus")
                {
                    return eventBus_;
                }
                else if (serviceName == "ConfigurationManager")
                {
                    return configManager_;
                }
                return nullptr;
            }
            
            void setEventBus(std::shared_ptr<PluginFramework::IEventBus> eventBus)
            {
                eventBus_ = eventBus;
            }
            
            void setConfigManager(std::shared_ptr<PluginFramework::IConfigurationManager> configManager)
            {
                configManager_ = configManager;
            }
            
        private:
            std::shared_ptr<PluginFramework::IEventBus> eventBus_;
            std::shared_ptr<PluginFramework::IConfigurationManager> configManager_;
        };
        
        std::shared_ptr<HostContext> createHostContext()
        {
            return std::make_shared<HostContext>();
        }
        
        void initializeCoreServices()
        {
            // 初始化事件总线
            auto eventBus = std::make_shared<SimpleEventBus>();
            hostContext_->setEventBus(eventBus);
            
            // 初始化配置管理器
            auto configManager = std::make_shared<SimpleConfigurationManager>();
            hostContext_->setConfigManager(configManager);
        }
        
        // 简单事件总线实现
        class SimpleEventBus : public PluginFramework::IEventBus
        {
        public:
            void subscribe(const std::string& eventType, EventHandler handler) override
            {
                std::lock_guard<std::mutex> lock(mutex_);
                subscribers_[eventType].push_back(handler);
            }
            
            void unsubscribe(const std::string& eventType, EventHandler handler) override
            {
                std::lock_guard<std::mutex> lock(mutex_);
                auto it = subscribers_.find(eventType);
                if (it != subscribers_.end())
                {
                    auto& handlers = it->second;
                    handlers.erase(
                        std::remove(handlers.begin(), handlers.end(), handler),
                        handlers.end());
                }
            }
            
            void publish(const std::shared_ptr<PluginFramework::IEvent>& event) override
            {
                std::vector<EventHandler> handlers;
                
                {
                    std::lock_guard<std::mutex> lock(mutex_);
                    auto it = subscribers_.find(event->getType());
                    if (it != subscribers_.end())
                    {
                        handlers = it->second;
                    }
                }
                
                for (const auto& handler : handlers)
                {
                    try
                    {
                        handler(event);
                    }
                    catch (const std::exception& e)
                    {
                        std::cerr << "Error in event handler: " << e.what() << std::endl;
                    }
                }
            }
            
            size_t getSubscriberCount(const std::string& eventType) const override
            {
                std::lock_guard<std::mutex> lock(mutex_);
                auto it = subscribers_.find(eventType);
                return it != subscribers_.end() ? it->second.size() : 0;
            }
            
        private:
            mutable std::mutex mutex_;
            std::unordered_map<std::string, std::vector<EventHandler>> subscribers_;
        };
        
        // 简单配置管理器实现
        class SimpleConfigurationManager : public PluginFramework::IConfigurationManager
        {
        public:
            std::shared_ptr<PluginFramework::IConfiguration> 
                getPluginConfiguration(const std::string& pluginId) override
            {
                std::lock_guard<std::mutex> lock(mutex_);
                
                auto it = configurations_.find(pluginId);
                if (it != configurations_.end())
                {
                    return it->second;
                }
                
                auto config = std::make_shared<JsonConfiguration>(pluginId + ".json");
                configurations_[pluginId] = config;
                return config;
            }
            
        private:
            mutable std::mutex mutex_;
            std::unordered_map<std::string, 
                std::shared_ptr<PluginFramework::IConfiguration>> configurations_;
        };
        
        // JSON配置实现
        class JsonConfiguration : public PluginFramework::IConfiguration
        {
        public:
            JsonConfiguration(const std::string& filePath)
                : filePath_(filePath)
            {
                load(filePath);
            }
            
            bool load(const std::string& filePath) override
            {
                // 实现JSON文件加载
                // 使用nlohmann/json或其他JSON库
                return true;
            }
            
            bool save(const std::string& filePath) override
            {
                // 实现JSON文件保存
                return true;
            }
            
            bool hasKey(const std::string& key) const override
            {
                std::lock_guard<std::mutex> lock(mutex_);
                return data_.find(key) != data_.end();
            }
            
            std::vector<std::string> getKeys() const override
            {
                std::lock_guard<std::mutex> lock(mutex_);
                std::vector<std::string> keys;
                for (const auto& pair : data_)
                {
                    keys.push_back(pair.first);
                }
                return keys;
            }
            
            template<typename T>
            T getValue(const std::string& key, const T& defaultValue) const
            {
                std::lock_guard<std::mutex> lock(mutex_);
                auto it = data_.find(key);
                if (it != data_.end())
                {
                    try
                    {
                        // 类型转换逻辑
                        return std::any_cast<T>(it->second);
                    }
                    catch (const std::bad_any_cast&)
                    {
                        return defaultValue;
                    }
                }
                return defaultValue;
            }
            
            template<typename T>
            void setValue(const std::string& key, const T& value)
            {
                std::lock_guard<std::mutex> lock(mutex_);
                data_[key] = value;
            }
            
        private:
            mutable std::mutex mutex_;
            std::string filePath_;
            std::unordered_map<std::string, std::any> data_;
        };
        
        std::shared_ptr<HostContext> hostContext_;
        std::shared_ptr<PluginManager> pluginManager_;
    };
}

// 主程序入口
int main(int argc, char* argv[])
{
    std::string pluginDirectory = "./plugins";
    
    if (argc > 1)
    {
        pluginDirectory = argv[1];
    }
    
    try
    {
        PluginHost::HostApplication app;
        app.run(pluginDirectory);
        return 0;
    }
    catch (const std::exception& e)
    {
        std::cerr << "Fatal error: " << e.what() << std::endl;
        return 1;
    }
}

📊 C# 与 C++ 实现对比

语言特性对比

特性 C# (.NET) C++
反射机制 完整支持,易于插件发现 有限支持,需要手动导出函数
内存管理 自动垃圾回收 手动内存管理,需要更谨慎
异常处理 结构化异常处理 异常处理,但跨DLL边界需小心
类型安全 强类型,运行时检查 强类型,编译时检查
跨平台性 优秀的跨平台支持 良好,但需要平台特定代码
热加载 Assembly.Unload,AppDomain隔离 复杂,需要平台特定DLL卸载
序列化 内置强大序列化支持 需要第三方库或手动实现

实现复杂度对比

csharp 复制代码
// C# 插件加载(简单)
Assembly assembly = Assembly.LoadFrom("plugin.dll");
var pluginTypes = assembly.GetTypes()
    .Where(t => typeof(IPlugin).IsAssignableFrom(t) && !t.IsAbstract);
    
foreach (var type in pluginTypes)
{
    var plugin = (IPlugin)Activator.CreateInstance(type);
    plugin.Initialize(context);
}
cpp 复制代码
// C++ 插件加载(复杂)
#ifdef _WIN32
    HMODULE handle = LoadLibraryW(L"plugin.dll");
#else
    void* handle = dlopen("plugin.so", RTLD_LAZY);
#endif

if (!handle) {
    // 错误处理
}

auto createFunc = reinterpret_cast<CreatePluginFunc>(GetProcAddress(handle, "createPlugin"));
auto destroyFunc = reinterpret_cast<DestroyPluginFunc>(GetProcAddress(handle, "destroyPlugin"));

if (!createFunc || !destroyFunc) {
    // 错误处理
}

IPlugin* plugin = createFunc();
plugin->initialize(context);

// 卸载时需要
plugin->shutdown();
destroyFunc(plugin);

#ifdef _WIN32
    FreeLibrary(handle);
#else
    dlclose(handle);
#endif

性能对比

指标 C# (.NET) C++
启动速度 较慢(JIT编译) 快(原生代码)
运行时性能 良好(JIT优化) 优秀(编译优化)
内存占用 较高(包含运行时) 较低
插件加载速度 快(Assembly加载) 快(DLL加载)
插件间调用 快(托管调用) 很快(直接调用)

安全性对比

csharp 复制代码
// C# 安全性高,支持代码访问安全
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public class SandboxedPluginLoader
{
    public IPlugin LoadInSandbox(string assemblyPath)
    {
        var appDomainSetup = new AppDomainSetup
        {
            ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
        };
        
        // 设置权限
        var permissionSet = new PermissionSet(PermissionState.None);
        permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
        
        var appDomain = AppDomain.CreateDomain(
            "Sandbox", 
            null, 
            appDomainSetup, 
            permissionSet);
        
        // 在沙箱中加载插件
        var loader = (PluginLoaderProxy)appDomain.CreateInstanceAndUnwrap(
            typeof(PluginLoaderProxy).Assembly.FullName,
            typeof(PluginLoaderProxy).FullName);
        
        return loader.LoadPlugin(assemblyPath);
    }
}
cpp 复制代码
// C++ 安全性较低,需要额外措施
class SecurePluginLoader
{
public:
    std::unique_ptr<IPlugin> loadWithRestrictions(const std::string& path)
    {
        // 1. 验证插件签名
        if (!verifySignature(path)) {
            throw std::runtime_error("Invalid plugin signature");
        }
        
        // 2. 在独立进程中加载插件(更安全但更复杂)
        // 使用进程间通信与插件交互
        
        // 3. 或使用系统安全特性(如Windows的Job Objects)
        
        return std::unique_ptr<IPlugin>(loadPlugin(path));
    }
    
private:
    bool verifySignature(const std::string& path)
    {
        // 使用数字签名验证
        // 平台特定实现
        return true;
    }
};

开发效率对比

csharp 复制代码
// C# 开发速度快,工具完善
[PluginMetadata("com.example.plugin", "Example Plugin", "1.0.0")]
public class ExamplePlugin : IPlugin, IDisposable
{
    // 自动属性,简洁语法
    public string Name { get; } = "Example Plugin";
    
    // async/await 支持
    public async Task InitializeAsync(IPluginContext context)
    {
        // LINQ 简化数据处理
        var configs = await LoadConfigsAsync();
        var validConfigs = configs.Where(c => c.IsValid)
                                 .Select(c => c.Value)
                                 .ToList();
        
        // 丰富的库支持
        await ProcessDataAsync(validConfigs);
    }
    
    // 自动内存管理
    private List<Resource> resources = new List<Resource>();
    
    public void Dispose()
    {
        // 简洁的资源清理
        foreach (var resource in resources)
        {
            resource.Dispose();
        }
    }
}
cpp 复制代码
// C++ 开发更底层,控制更精细
class ExamplePlugin : public IPlugin
{
public:
    ExamplePlugin() 
        : name_("Example Plugin")
        , resources_()
    {
        // 手动资源管理
        resources_.reserve(10);
    }
    
    ~ExamplePlugin()
    {
        // 必须手动清理
        for (auto& resource : resources_)
        {
            delete resource;
        }
    }
    
    bool initialize(std::shared_ptr<IPluginContext> context) override
    {
        // 手动处理异步
        auto configs = loadConfigs();
        std::vector<ConfigValue> validConfigs;
        
        std::copy_if(configs.begin(), configs.end(),
                    std::back_inserter(validConfigs),
                    [](const Config& c) { return c.isValid(); });
        
        // 手动内存管理
        auto processor = new DataProcessor();
        resources_.push_back(processor);
        
        return processor->process(validConfigs);
    }
    
private:
    std::string name_;
    std::vector<Resource*> resources_; // 手动管理
};

⚠️ 挑战与注意事项

1. 版本兼容性问题

csharp 复制代码
// 版本兼容性解决方案
public interface IPluginV2 : IPluginV1
{
    // 新功能
    Task<PluginResult> ExecuteWithOptionsAsync(ExecutionOptions options);
    
    // 保持向后兼容
    new Task ExecuteAsync()
    {
        return ExecuteWithOptionsAsync(ExecutionOptions.Default);
    }
}

// 版本适配器模式
public class PluginVersionAdapter : IPluginV2
{
    private readonly IPluginV1 _legacyPlugin;
    
    public PluginVersionAdapter(IPluginV1 legacyPlugin)
    {
        _legacyPlugin = legacyPlugin;
    }
    
    public async Task<PluginResult> ExecuteWithOptionsAsync(ExecutionOptions options)
    {
        // 将新API适配到旧插件
        if (_legacyPlugin is IPluginV2 v2Plugin)
        {
            return await v2Plugin.ExecuteWithOptionsAsync(options);
        }
        else
        {
            // 回退到旧版本行为
            await _legacyPlugin.ExecuteAsync();
            return PluginResult.Success();
        }
    }
}

// 插件版本检测
public class VersionCompatibilityChecker
{
    public CompatibilityResult CheckCompatibility(
        PluginInfo pluginInfo, 
        Version hostVersion)
    {
        var pluginVersion = pluginInfo.Version;
        
        // 检查主版本兼容性
        if (pluginVersion.Major > hostVersion.Major)
        {
            return CompatibilityResult.Incompatible(
                $"Plugin requires host version {pluginVersion.Major}.x.x");
        }
        
        // 检查API兼容性
        var apiVersion = GetApiVersion(pluginInfo);
        if (!IsApiCompatible(apiVersion))
        {
            return CompatibilityResult.Incompatible(
                $"Plugin uses incompatible API version {apiVersion}");
        }
        
        // 检查依赖兼容性
        foreach (var dependency in pluginInfo.Dependencies)
        {
            var depResult = CheckDependencyCompatibility(dependency);
            if (!depResult.IsCompatible)
            {
                return depResult;
            }
        }
        
        return CompatibilityResult.Compatible();
    }
}

2. 安全性挑战

csharp 复制代码
// 插件安全沙箱
public class PluginSecuritySandbox : MarshalByRefObject
{
    private readonly PermissionSet _permissions;
    private readonly AppDomain _sandboxDomain;
    private readonly List<IPlugin> _loadedPlugins;
    
    public PluginSecuritySandbox()
    {
        // 定义最小权限集
        _permissions = new PermissionSet(PermissionState.None);
        _permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
        _permissions.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, 
            GetTrustedDirectories()));
        
        // 创建沙箱域
        var appDomainSetup = new AppDomainSetup
        {
            ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
            ApplicationName = "PluginSandbox"
        };
        
        _sandboxDomain = AppDomain.CreateDomain(
            "PluginSandbox",
            null,
            appDomainSetup,
            _permissions);
        
        _loadedPlugins = new List<IPlugin>();
    }
    
    public IPlugin LoadPlugin(string assemblyPath)
    {
        // 验证插件签名
        if (!VerifyPluginSignature(assemblyPath))
        {
            throw new SecurityException("Plugin signature verification failed");
        }
        
        // 在沙箱中加载
        var loaderType = typeof(SandboxedPluginLoader);
        var loader = (SandboxedPluginLoader)_sandboxDomain.CreateInstanceAndUnwrap(
            loaderType.Assembly.FullName,
            loaderType.FullName);
        
        var plugin = loader.LoadPlugin(assemblyPath);
        _loadedPlugins.Add(plugin);
        
        return plugin;
    }
    
    public void ExecutePlugin(string pluginId, object parameters)
    {
        var plugin = _loadedPlugins.FirstOrDefault(p => p.Id == pluginId);
        if (plugin != null)
        {
            try
            {
                // 监控插件执行
                using (var monitor = new ResourceMonitor())
                {
                    plugin.Execute(parameters);
                    
                    // 检查资源使用
                    if (monitor.MemoryUsage > MAX_MEMORY)
                    {
                        throw new ResourceLimitExceededException("Memory limit exceeded");
                    }
                }
            }
            catch (Exception ex)
            {
                // 隔离插件异常
                LogSecurityEvent($"Plugin {pluginId} caused exception: {ex.Message}");
                throw new PluginSecurityException("Plugin execution failed", ex);
            }
        }
    }
    
    private bool VerifyPluginSignature(string assemblyPath)
    {
        // 实现数字签名验证
        using (var cert = new X509Certificate2(assemblyPath))
        {
            // 检查证书有效性
            return cert.Verify();
        }
    }
    
    public void Dispose()
    {
        foreach (var plugin in _loadedPlugins)
        {
            try
            {
                plugin.Dispose();
            }
            catch (Exception ex)
            {
                LogSecurityEvent($"Error disposing plugin: {ex.Message}");
            }
        }
        
        AppDomain.Unload(_sandboxDomain);
    }
}

3. 性能优化

csharp 复制代码
// 插件性能监控与优化
public class PluginPerformanceOptimizer
{
    private readonly ConcurrentDictionary<string, PluginPerformanceStats> _stats;
    private readonly Timer _monitoringTimer;
    
    public PluginPerformanceOptimizer()
    {
        _stats = new ConcurrentDictionary<string, PluginPerformanceStats>();
        _monitoringTimer = new Timer(MonitorPlugins, null, 
            TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30));
    }
    
    private void MonitorPlugins(object state)
    {
        foreach (var kvp in _stats)
        {
            var pluginId = kvp.Key;
            var stats = kvp.Value;
            
            // 检测性能问题
            if (stats.AverageExecutionTime > TimeSpan.FromSeconds(1))
            {
                LogPerformanceWarning($"Plugin {pluginId} is slow: {stats.AverageExecutionTime}");
                
                // 自动优化策略
                if (stats.ConcurrentCalls > 1)
                {
                    OptimizeConcurrency(pluginId);
                }
                
                if (stats.MemoryUsage > 100 * 1024 * 1024) // 100MB
                {
                    OptimizeMemory(pluginId);
                }
            }
        }
    }
    
    private void OptimizeConcurrency(string pluginId)
    {
        // 实现并发优化策略
        // 1. 限制并发调用
        // 2. 实现请求队列
        // 3. 使用连接池
    }
    
    private void OptimizeMemory(string pluginId)
    {
        // 内存优化策略
        // 1. 卸载并重新加载插件
        // 2. 清理缓存
        // 3. 减少资源保留时间
    }
    
    public async Task<T> ExecuteWithOptimization<T>(
        string pluginId, 
        Func<Task<T>> operation)
    {
        var stopwatch = Stopwatch.StartNew();
        var startMemory = GC.GetTotalMemory(false);
        
        try
        {
            var result = await operation();
            
            var elapsed = stopwatch.Elapsed;
            var endMemory = GC.GetTotalMemory(false);
            var memoryUsed = Math.Max(0, endMemory - startMemory);
            
            UpdateStats(pluginId, elapsed, memoryUsed, success: true);
            
            return result;
        }
        catch (Exception ex)
        {
            UpdateStats(pluginId, stopwatch.Elapsed, 0, success: false);
            throw;
        }
    }
    
    private void UpdateStats(string pluginId, TimeSpan elapsed, 
                           long memoryUsed, bool success)
    {
        var stats = _stats.GetOrAdd(pluginId, 
            id => new PluginPerformanceStats());
        
        lock (stats)
        {
            stats.TotalCalls++;
            if (success) stats.SuccessfulCalls++;
            
            stats.TotalExecutionTime += elapsed;
            stats.AverageExecutionTime = TimeSpan.FromTicks(
                stats.TotalExecutionTime.Ticks / stats.TotalCalls);
            
            stats.MaxMemoryUsage = Math.Max(stats.MaxMemoryUsage, memoryUsed);
            stats.AverageMemoryUsage = (stats.AverageMemoryUsage * (stats.TotalCalls - 1) 
                + memoryUsed) / stats.TotalCalls;
            
            stats.LastCallTime = DateTime.UtcNow;
        }
    }
}

4. 依赖管理

csharp 复制代码
// 高级依赖解析器
public class AdvancedDependencyResolver
{
    public class DependencyResolutionResult
    {
        public bool Success { get; set; }
        public List<string> LoadOrder { get; set; }
        public List<DependencyConflict> Conflicts { get; set; }
        public List<string> MissingDependencies { get; set; }
        
        public void AddConflict(string pluginA, string pluginB, 
                               Version versionA, Version versionB)
        {
            Conflicts ??= new List<DependencyConflict>();
            Conflicts.Add(new DependencyConflict
            {
                PluginA = pluginA,
                PluginB = pluginB,
                VersionA = versionA,
                VersionB = versionB
            });
        }
    }
    
    public DependencyResolutionResult ResolveDependencies(
        IEnumerable<PluginInfo> plugins)
    {
        var result = new DependencyResolutionResult();
        
        // 构建依赖图
        var graph = BuildDependencyGraph(plugins);
        
        // 检测循环依赖
        var cycles = DetectCycles(graph);
        if (cycles.Any())
        {
            result.Success = false;
            result.Conflicts = cycles.Select(c => new DependencyConflict
            {
                Type = ConflictType.CircularDependency,
                Description = $"Circular dependency: {string.Join(" -> ", c)}"
            }).ToList();
            return result;
        }
        
        // 检测版本冲突
        var versionConflicts = DetectVersionConflicts(plugins);
        if (versionConflicts.Any())
        {
            result.Success = false;
            result.Conflicts = versionConflicts;
            return result;
        }
        
        // 拓扑排序
        try
        {
            result.LoadOrder = TopologicalSort(graph);
            result.Success = true;
        }
        catch (InvalidOperationException ex)
        {
            result.Success = false;
            result.Conflicts = new List<DependencyConflict>
            {
                new DependencyConflict
                {
                    Type = ConflictType.UnresolvableDependency,
                    Description = ex.Message
                }
            };
        }
        
        return result;
    }
    
    private List<List<string>> DetectCycles(Dictionary<string, List<string>> graph)
    {
        var cycles = new List<List<string>>();
        var visited = new HashSet<string>();
        var recursionStack = new HashSet<string>();
        
        foreach (var node in graph.Keys)
        {
            if (!visited.Contains(node))
            {
                FindCycles(node, graph, visited, recursionStack, 
                          new List<string>(), cycles);
            }
        }
        
        return cycles;
    }
    
    private void FindCycles(string node, Dictionary<string, List<string>> graph,
                           HashSet<string> visited, HashSet<string> recursionStack,
                           List<string> path, List<List<string>> cycles)
    {
        visited.Add(node);
        recursionStack.Add(node);
        path.Add(node);
        
        if (graph.ContainsKey(node))
        {
            foreach (var neighbor in graph[node])
            {
                if (!visited.Contains(neighbor))
                {
                    FindCycles(neighbor, graph, visited, recursionStack, path, cycles);
                }
                else if (recursionStack.Contains(neighbor))
                {
                    // 找到循环
                    var cycleStart = path.IndexOf(neighbor);
                    if (cycleStart >= 0)
                    {
                        var cycle = path.Skip(cycleStart).ToList();
                        cycle.Add(neighbor); // 闭合循环
                        cycles.Add(cycle);
                    }
                }
            }
        }
        
        recursionStack.Remove(node);
        path.RemoveAt(path.Count - 1);
    }
    
    private List<DependencyConflict> DetectVersionConflicts(
        IEnumerable<PluginInfo> plugins)
    {
        var conflicts = new List<DependencyConflict>();
        var pluginVersions = plugins.ToDictionary(p => p.Id, p => p.Version);
        
        // 检查直接版本冲突
        foreach (var plugin in plugins)
        {
            foreach (var dependency in plugin.Dependencies)
            {
                if (pluginVersions.TryGetValue(dependency.PluginId, out var availableVersion))
                {
                    if (dependency.MinVersion > availableVersion || 
                        (dependency.MaxVersion != null && 
                         dependency.MaxVersion < availableVersion))
                    {
                        conflicts.Add(new DependencyConflict
                        {
                            PluginA = plugin.Id,
                            PluginB = dependency.PluginId,
                            VersionA = plugin.Version,
                            VersionB = availableVersion,
                            Type = ConflictType.VersionMismatch,
                            Description = $"Plugin {plugin.Id} requires {dependency.PluginId} " +
                                        $"version {dependency.MinVersion}-{dependency.MaxVersion}, " +
                                        $"but found {availableVersion}"
                        });
                    }
                }
            }
        }
        
        return conflicts;
    }
}

🎯 总结:何时使用插件式架构?

适用场景

  1. 需要高度可扩展的应用程序

    • 内容管理系统(CMS)
    • 集成开发环境(IDE)
    • 游戏引擎
    • 数据分析平台
  2. 多团队协作开发

    • 不同团队负责不同功能模块
    • 需要独立开发、测试和部署
  3. 需要动态功能的系统

    • 支持热插拔功能
    • 运行时功能扩展
    • 模块化更新
  4. 第三方扩展支持

    • 允许第三方开发者扩展功能
    • 应用商店或插件市场

不适用场景

  1. 小型简单应用

    • 功能固定,无需扩展
    • 开发团队小,沟通成本低
  2. 性能极端敏感的系统

    • 插件调用有额外开销
    • 实时性要求极高的系统
  3. 安全要求极高的环境

    • 插件可能引入安全风险
    • 如金融交易核心系统
  4. 资源极度受限的环境

    • 嵌入式系统
    • 内存和计算资源严格限制

决策矩阵

考虑因素 适合插件架构 不适合插件架构
功能变化频率 高频变化 低频或不变
团队规模 多个独立团队 小型紧密团队
部署需求 独立部署模块 整体部署
技术栈 多种技术栈 单一技术栈
维护周期 长期维护 短期项目
第三方扩展 需要 不需要

实施建议

  1. 渐进式采用

    复制代码
    阶段1: 定义核心插件接口
    阶段2: 将稳定功能重构为插件
    阶段3: 实现插件发现和加载机制
    阶段4: 添加插件管理功能
    阶段5: 开放第三方插件开发
  2. 工具链建设

    • 插件开发SDK
    • 插件调试工具
    • 插件打包和签名工具
    • 插件市场/仓库
  3. 社区建设

    • 开发者文档和教程
    • 示例插件库
    • 开发者论坛
    • 插件审核机制

未来趋势

  1. 微内核架构演进
  2. WebAssembly插件系统
  3. 云原生插件架构
  4. AI驱动的插件推荐
  5. 区块链验证的插件安全

插件式架构不仅是技术选择,更是软件设计哲学的体现。它代表着开放、扩展和演化的思想,是现代软件系统应对复杂性和变化的重要武器。无论选择C#、C++还是其他语言,理解插件架构的核心原则并合理应用,都能显著提升软件系统的长期价值。


本文详细探讨了插件式开发的各个方面,从理论基础到具体实现,从C#到C++,从优势到挑战。希望这篇超过10000字的文章能为您的插件式开发实践提供全面而有价值的参考。

相关推荐
数字新视界1 小时前
动环监控信创适配在智能机房管理中的应用价值与未来展望
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
爱和冰阔落1 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
程序员沉梦听雨1 小时前
WSL2的安装与使用
linux·wsl
微小的鱼2 小时前
Linux的渲染与显示系统链路
android·java·linux
lisanmengmeng2 小时前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器
严肃小白兔2 小时前
Cloudflare 更新 API Token 管理:从最小权限到自动化凭据安全
网络·安全·自动化
Android系统攻城狮3 小时前
Linux FFmpeg深度解析之av_write_frame调用流程与实战(三十三)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
上火的金鱼妹3 小时前
k8s生产实际问题排查(网关,数据库读写等)
运维·服务器
Linux-lucky14 小时前
45-Linux学习之旅之防火墙与WEB加固
linux·前端·网络·学习·ubuntu
禁默15 小时前
启元 Q1 二次开发实践:Ubuntu 部署与仿真验证,从 PrimeConsole 到 ROS 2 Humble + RViz
linux·运维·ubuntu