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

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

🤔 什么是插件式开发?

插件式开发(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字的文章能为您的插件式开发实践提供全面而有价值的参考。

相关推荐
txzz88882 小时前
CentOS-Stream-10 搭建YUM源Web服务器
linux·运维·centos·yum源·linux系统更新·centos系统更新·自建web yum源
Molesidy2 小时前
【Linux】基于Imx6ull Pro开发板和platform_device+platform_driver框架的LED驱动设计以及上机测试
linux·驱动开发
我科绝伦(Huanhuan Zhou)3 小时前
Linux系统硬件时钟与系统时钟深度解析及同步实操指南
linux·运维·服务器
k***92163 小时前
【Linux】进程概念(六):地址空间核心机制
linux·运维·算法
李白同学3 小时前
Linux:调试器-gdb/cgdb使用
linux·服务器·c语言·c++
保持低旋律节奏3 小时前
linux——进程调度(时间片+优先级轮转调度算法O(1))
linux·运维·算法
少年、潜行3 小时前
F1C100/200S学习笔记(3)-- 裸机开发
linux·笔记·学习·驱动·裸机·f1c200s
老王熬夜敲代码3 小时前
网路编程--协议
linux·网络·笔记
虾..3 小时前
Linux 进程池小程序
linux·c++·小程序