如何无需添加FrameworkReference,用AssemblyLoadContext加载.NET程序集
解决无需添加FrameworkReference即可加载ASP.NET Core/WPF程序集的问题
问题核心在于:ASP.NET Core和WPF的核心程序集属于共享框架,它们并不存在于目标程序集的输出目录中。你的自定义AssemblyLoadContext默认只会从目标程序集的依赖目录查找,因此找不到这些共享框架程序集,从而抛出ReflectionTypeLoadException。
解决方案:让自定义AssemblyLoadContext回退到默认上下文加载共享框架程序集
修改AssemblyResolver的Load方法,当本地无法解析程序集时,委托给默认AssemblyLoadContext去加载(默认上下文会自动处理共享框架的程序集查找逻辑)。
修改后的完整代码:
using System.Reflection; using System.Runtime.Loader; var path = @"..\..\..\..\WebApplication1\bin\Debug\net8.0\WebApplication1.dll"; //var path = @"..\..\..\..\WpfApp1\bin\Debug\net8.0-windows\WpfApp1.dll"; //var path = @"..\..\..\..\ClassLibrary1\bin\Debug\net8.0\ClassLibrary1.dll"; var resolver = new AssemblyResolver(path); var assembly = resolver.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(path))); try { foreach (var type in assembly.GetTypes()) { System.Diagnostics.Debug.WriteLine(type.FullName); } } catch (ReflectionTypeLoadException ex) { // 可选:处理部分类型加载失败的情况,输出已成功加载的类型 foreach (var type in ex.Types.Where(t => t != null)) { System.Diagnostics.Debug.WriteLine($"已加载类型:{type.FullName}"); } // 输出加载失败的具体原因 foreach (var loaderEx in ex.LoaderExceptions) { System.Diagnostics.Debug.WriteLine($"加载异常:{loaderEx.Message}"); } } public class AssemblyResolver : AssemblyLoadContext { private readonly AssemblyDependencyResolver _resolver; public AssemblyResolver(string path) { _resolver = new AssemblyDependencyResolver(path); } protected override Assembly? Load(AssemblyName assemblyName) { // 先尝试从目标程序集的依赖目录加载私有程序集 var assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName); if (assemblyPath != null) { return LoadFromAssemblyPath(assemblyPath); } // 本地找不到时,委托给默认AssemblyLoadContext加载共享框架程序集 return Default.LoadFromAssemblyName(assemblyName); } protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) { var libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName); return libraryPath != null ? LoadUnmanagedDllFromPath(libraryPath) : IntPtr.Zero; } }
关键说明:
- 回退逻辑:
Default.LoadFromAssemblyName(assemblyName)会触发.NET运行时的标准程序集查找流程,自动定位共享框架中的程序集,无需在测试项目中提前添加任何FrameworkReference。 - 异常兼容:新增
ReflectionTypeLoadException捕获逻辑,即使仍有部分类型因依赖缺失加载失败,也能保留已成功加载的类型信息,并排查具体错误原因。 - 通用性:该方案适配所有依赖共享框架的程序集(ASP.NET Core、WPF、WinForms等),无需提前知晓目标程序集的依赖框架类型。
内容的提问来源于stack exchange,提问作者usausa
相关产品推荐
相关产品推荐

