You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何高效从外部程序集扩展ProcessingManager功能?

优化外部程序集扩展ProcessingManager的方案

替代全程序集遍历的可行方案

1. 用MEF框架实现自动发现

MEF是.NET内置的可扩展性框架,专门解决插件式扩展场景,完全匹配你的需求:

  • 在外部程序集的IProcessor实现类上标记[Export(typeof(IProcessor))]
  • 在ProcessingManager中通过CompositionContainer批量导入所有实现,不用遍历所有程序集
  • 示例代码:
    // 外部程序集的处理器实现
    [Export(typeof(IProcessor))]
    public class DemoProcessor : IProcessor
    {
        public void Process(TypeDefinition typeDef)
        {
            // 自定义处理逻辑
        }
    }
    
    // ProcessingManager中的加载逻辑
    var pluginCatalog = new DirectoryCatalog("你的插件存放目录");
    var container = new CompositionContainer(pluginCatalog);
    var allProcessors = container.GetExportedValues<IProcessor>();
    
    foreach (var processor in allProcessors)
    {
        processor.Process(targetTypeDef);
    }
    
  • 优点:自动识别指定接口的实现,支持按需加载,性能比全程序集遍历高很多

2. 配置文件指定扩展程序集

在主程序的配置文件(如appsettings.json)里列出所有包含IProcessor实现的程序集名称,只加载这些指定的程序集:

  • 配置示例:
    {
      "ProcessorAssemblies": [
        "OrderProcessor.dll",
        "UserProcessor.dll"
      ]
    }
    
  • 加载逻辑:
    var assemblyNames = Configuration.GetSection("ProcessorAssemblies").Get<string[]>();
    foreach (var assemblyName in assemblyNames)
    {
        var assemblyPath = Path.Combine("插件目录", assemblyName);
        var assembly = Assembly.LoadFrom(assemblyPath);
        
        var processorTypes = assembly.GetTypes()
            .Where(t => typeof(IProcessor).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);
        
        foreach (var type in processorTypes)
        {
            var processor = (IProcessor)Activator.CreateInstance(type);
            // 将处理器加入ProcessingManager管理
        }
    }
    
  • 优点:完全可控,性能最优,适合明确知道扩展程序集的场景

3. 用AssemblyLoadContext按需加载

结合AssemblyLoadContext加载指定目录下的程序集,同时跳过无效程序集,减少不必要的加载:

  • 核心代码:
    var processorLoadContext = new AssemblyLoadContext("ProcessorContext", isCollectible: true);
    var pluginDir = new DirectoryInfo("插件目录");
    
    foreach (var dllFile in pluginDir.GetFiles("*.dll"))
    {
        try
        {
            var assembly = processorLoadContext.LoadFromAssemblyPath(dllFile.FullName);
            var processorTypes = assembly.GetTypes()
                .Where(t => typeof(IProcessor).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);
            
            if (processorTypes.Any())
            {
                // 实例化并管理这些处理器
            }
        }
        catch (BadImageFormatException)
        {
            // 跳过非.NET程序集
            continue;
        }
    }
    
  • 优点:隔离扩展程序集的加载上下文,避免影响主程序,同时只处理可能包含目标实现的程序集

方案对比

以上三种方案都避免了遍历系统所有程序集的低效操作,要么依赖框架自动发现,要么通过配置明确范围,要么按需筛选加载,在性能和可控性上都远优于原有的全遍历方式。

内容的提问来源于stack exchange,提问作者FeXseven

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 01:16:27