动态加载含.NET Framework依赖的.NET 6库失败,项目引用则正常
解决.NET 6动态加载包装DLL时找不到.NET Framework依赖的问题
问题根源
.NET 6+的默认AssemblyLoadContext(ALC)依赖deps.json文件解析程序集依赖。动态加载.NET 6包装DLL时,若主应用的deps.json未包含该包装DLL的.NET Framework依赖信息,ALC无法定位对应DLL文件。添加项目引用时MSBuild会自动更新deps.json补充依赖项,因此能正常加载;但动态加载场景下缺少该清单,就会触发找不到文件的错误。
解决方案:自定义AssemblyLoadContext处理依赖
1. 实现自定义AssemblyLoadContext
继承AssemblyLoadContext并重写依赖加载逻辑,手动指定.NET Framework DLL的搜索路径,让ALC能定位到这些非标准依赖:
using System.Reflection; using System.IO; public class LegacyAssemblyLoadContext : AssemblyLoadContext { private readonly string _dependencySearchPath; // 构造函数传入依赖DLL所在路径 public LegacyAssemblyLoadContext(string searchPath) : base(isCollectible: true) { _dependencySearchPath = searchPath; } protected override Assembly? Load(AssemblyName assemblyName) { // 优先从指定路径加载目标依赖 var targetDll = Path.Combine(_dependencySearchPath, $"{assemblyName.Name}.dll"); if (File.Exists(targetDll)) { return LoadFromAssemblyPath(targetDll); } // 其他依赖交给默认上下文处理 return Default.LoadFromAssemblyName(assemblyName); } }
2. 使用自定义上下文加载包装DLL
在.NET 6 WinForms应用中,通过自定义ALC加载包装DLL,确保.NET Framework依赖DLL与包装DLL处于同一目录(或指定正确的搜索路径):
// 包装DLL的路径 var wrapperDllPath = @"C:\YourOutputPath\MCCDAQ_Wrapper.dll"; // 依赖DLL所在路径(假设和包装DLL同目录) var legacyDllDir = Path.GetDirectoryName(wrapperDllPath); // 创建自定义加载上下文 var alc = new LegacyAssemblyLoadContext(legacyDllDir); // 加载包装DLL var wrapperAssembly = alc.LoadFromAssemblyPath(wrapperDllPath); // 示例:创建包装类实例并调用方法 var wrapperType = wrapperAssembly.GetType("MCCDAQ_Wrapper.YourWrapperClass"); var wrapperInstance = Activator.CreateInstance(wrapperType); var method = wrapperType.GetMethod("YourMethod"); method?.Invoke(wrapperInstance, null);
3. 适配多个.NET Framework DLL的通用配置
- 所有待封装的.NET Framework DLL,在包装DLL的项目中设置为
Copy to Output Directory = 始终复制,确保发布时这些DLL与包装DLL放在同一目录。 - 若依赖的DLL存在嵌套依赖,统一将所有依赖文件放到同一目录,自定义ALC会通过重写的
Load方法自动找到它们。 - 避免依赖自动生成的
deps.json,动态加载场景下该文件内容可能不完整或无法被ALC读取。
为什么添加项目引用能正常运行
添加包装DLL的项目引用时,MSBuild会自动将包装DLL的依赖项写入主应用的deps.json文件,默认的AssemblyLoadContext会根据该清单找到.NET Framework依赖DLL。而动态加载时缺少这个自动生成的依赖清单,因此需要通过自定义ALC手动处理依赖加载。
内容的提问来源于stack exchange,提问作者Paul de Boer
相关产品推荐
相关产品推荐

