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

使用Scrutor加载外部程序集依赖项的问题求助

解决外部程序集依赖加载问题

完全可行,核心思路是利用CLR的程序集解析事件,当CLR无法找到依赖程序集时,手动从指定外部文件夹加载对应的依赖文件。以下是具体实现方案:

步骤1:注册全局程序集解析事件

在加载外部程序集前,注册AppDomain.CurrentDomain.AssemblyResolve事件——该事件会在CLR找不到所需程序集时触发,我们可以在事件处理逻辑中从外部文件夹查找并加载依赖。

步骤2:修改扩展方法并实现解析逻辑

调整原扩展方法,补充依赖解析的逻辑,同时优化程序集加载方式:

public static IImplementationTypeSelector FromExternalAssemblies(
    this IAssemblySelector selector, ConfigurationManager configurationManager)
{
    var virgilioMainFolder = configurationManager["ExternalFolder:Folder"];
    var assembliesToLoad = new List<string>();
    configurationManager.GetSection("ExternalFolder:AssembliesToLoad")
        .Bind(assembliesToLoad);
    var assemblies = new List<Assembly>();

    // 确保事件只注册一次,避免重复调用时触发多次逻辑
    AppDomain.CurrentDomain.AssemblyResolve -= ResolveExternalAssembly;
    AppDomain.CurrentDomain.AssemblyResolve += ResolveExternalAssembly;

    foreach (var pathAssembly in assembliesToLoad)
    {
        try
        {
            var fullPathAssembly = Path.Combine(virgilioMainFolder, pathAssembly);
            // 用LoadFrom替代LoadFile:LoadFrom会尝试加载直接依赖(同文件夹下),减少解析压力
            var assembly = Assembly.LoadFrom(fullPathAssembly);
            assemblies.Add(assembly);
        }
        catch (Exception)
        {
            continue;
        }
    }

    return selector.FromAssemblies(assemblies.ToArray());

    // 局部方法:处理依赖程序集的解析逻辑
    Assembly? ResolveExternalAssembly(object? sender, ResolveEventArgs args)
    {
        var assemblyName = new AssemblyName(args.Name);
        // 拼接依赖程序集的路径
        var assemblyPath = Path.Combine(virgilioMainFolder, $"{assemblyName.Name}.dll");
        
        if (File.Exists(assemblyPath))
        {
            return Assembly.LoadFrom(assemblyPath);
        }

        // 若依赖分布在子文件夹,可扩展此处逻辑(比如递归遍历外部文件夹)
        return null;
    }
}

关键细节说明

  • LoadFrom与LoadFile的区别:LoadFile仅加载指定的单个程序集,完全不处理依赖;LoadFrom会自动加载同文件夹下的直接依赖,能减少一部分解析工作。
  • 事件幂等性:先移除再添加事件处理程序,避免多次调用扩展方法时重复注册,导致逻辑重复执行。
  • 强命名程序集处理:如果依赖是强命名程序集,要确保版本、公钥令牌与引用要求完全匹配,否则CLR会拒绝加载。
  • 异常防护:实际使用时建议在ResolveExternalAssembly中添加异常捕获,避免单个依赖加载失败导致整个应用崩溃。

额外注意事项

  • 若依赖程序集已被主应用域加载过,CLR会直接复用已加载的版本,不会触发解析事件。
  • 若是插件化场景,后续卸载插件时建议移除事件处理程序,避免内存泄漏(长期运行的服务需重点关注)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:10:24