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

通过AssemblyResolve加载程序集为何出现方法未找到异常?

动态加载DLL时AssemblyResolve事件导致MissingMethodException的原因

问题描述

我开发了一款从其他文件夹动态加载DLL的应用,目标DLL(MyDLL.dll)依赖Microsoft.Extensions.Logging.dll。直接先加载依赖DLL再加载目标DLL时,调用方法正常运行;但通过AppDomain的AssemblyResolve事件加载依赖DLL时,调用目标DLL方法会触发MissingMethodException,提示找不到指定的AddConsole方法。已确认两种方式加载的依赖程序集路径完全一致,想知道为什么表现不同?

正常运行代码示例

void f()
{
   Assembly.LoadFrom(@"C:\DllFolder\Microsoft.Extensions.Logging.dll");
   Assembly mydll = Assembly.LoadFrom(@"C:\DllFolder\MyDLL.dll");
   CallMethodFromMyDll(mydll); // 运行正常 :-)
}

异常场景代码示例

void f()
{
   AppDomain.CurrentDomain.AssemblyResolve += MyAssemblyResolveFunction;
   Assembly mydll = Assembly.LoadFrom(@"C:\DllFolder\MyDLL.dll");
   CallMethodFromMyDll(mydll); // 触发MissingMethodException :-(
}

Assembly MyAssemblyResolveFunction(object sender, ResolveEventArgs args)
{
   var assembly = Assembly.LoadFrom(@"C:\DllFolder\Microsoft.Extensions.Logging.dll");

   if (assembly != null)
   {
        // 代码确实执行到这里了!
        return assembly;
   }

   return null;
}

异常信息

Method not found: 'Microsoft.Extensions.Logging.ILoggerFactory Microsoft.Extensions.Logging.ConsoleLoggerExtensions.AddConsole(Microsoft.Extensions.Logging.ILoggerFactory, Microsoft.Extensions.Logging.LogLevel)'.

原因分析与解决方案

核心问题:程序集绑定上下文不匹配

直接调用Assembly.LoadFrom加载依赖DLL时,程序集会被加载到加载上下文(Load Context)中;而通过AssemblyResolve事件返回的程序集,默认会被加载到无上下文(No Context)中。

MyDLL.dll编译时引用的是加载上下文中的Microsoft.Extensions.Logging.dll,当运行时依赖的程序集处于无上下文时,CLR会认为这是两个不同的程序集实例——即使它们路径相同、版本一致,也会因为上下文差异导致方法绑定失败,触发MissingMethodException。

验证方式

你可以在两种场景下分别输出Microsoft.Extensions.Logging.dll的Assembly.LoadContext属性值,会发现直接加载时属于DefaultLoadContext,而通过AssemblyResolve返回的则是null(无上下文)。

修复方案

修改AssemblyResolve事件中的加载方式,确保依赖DLL被加载到加载上下文:

Assembly MyAssemblyResolveFunction(object sender, ResolveEventArgs args)
{
    // 使用AssemblyLoadContext.Default.LoadFromAssemblyPath替代LoadFrom
    var assemblyPath = @"C:\DllFolder\Microsoft.Extensions.Logging.dll";
    return AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyPath);
}

或者,也可以提前将依赖DLL的路径添加到应用的程序集探测路径,让CLR自动找到并加载到正确上下文:

// 在加载MyDLL前执行
AppDomain.CurrentDomain.AppendPrivatePath(@"C:\DllFolder");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 21:35:17