.NET Core/.NET 5+ 中应使用可卸载的 AssemblyLoadContext(isCollectible: true)替代不可卸载的 Assembly.LoadFrom;需重写 Load 方法、显式调用 Unload、配合 AssemblyDependencyResolver 解析依赖,并注意类型可见性与动态程序集限制。

AssemblyLoadContext.Load 适用于 .NET Core / .NET 5+ 的隔离加载
在 .NET Core 及更高版本中,Assembly.LoadFrom 会把程序集加载进默认上下文,无法卸载,容易造成内存泄漏。真正可卸载的动态加载必须用 AssemblyLoadContext。
关键点:
- 继承
AssemblyLoadContext并重写Load方法,控制依赖解析逻辑 - 新建实例时传
isCollectible: true,否则仍不可卸载 - 加载后必须显式调用
context.Unload(),且需确保无任何托管引用残留(包括事件订阅、静态字段、委托缓存)
var context = new AssemblyLoadContext(isCollectible: true);
try
{
var asm = context.LoadFromAssemblyPath(@"C:\plugins\MyPlugin.dll");
// 使用 asm 创建类型实例等...
}
finally
{
context.Unload(); // 必须调用,但可能阻塞直到 GC 回收完成
}
Assembly.LoadFrom 在 .NET Framework 中最常用但不可卸载
如果你还在用 .NET Framework(如 4.8),Assembly.LoadFrom 是最直接的方式,但它会把程序集加载进 Default 上下文,整个进程生命周期内无法释放。
常见误用:
- 反复调用
LoadFrom同一路径 → 抛出FileLoadException:“不能为同一个程序集加载多个版本” - 试图用
AppDomain.Unload卸载 → .NET Framework 中仅对非默认 AppDomain 有效,且已标记为过时
try
{
var asm = Assembly.LoadFrom(@"C:\legacy\Tool.dll");
var type = asm.GetType("Tool.Processor");
var inst = Activator.CreateInstance(type);
}
catch (FileLoadException ex) when (ex.Message.Contains("same assembly"))
{
// 已加载,从 AppDomain.CurrentDomain.GetAssemblies() 查找复用
}
使用 AssemblyDependencyResolver 避免 MissingMethodException
动态加载的程序集若依赖其他 DLL(比如 Newtonsoft.Json 或自定义基础库),不处理依赖会导致运行时报 MissingMethodException 或 FileNotFoundException。
沙之丘企业网站程序是一个以asp.net(C#) 4.0 +access进行开发的企业网站源码。主要功能:1、产品、设备、新闻系统2、留言信息直接发邮件到相关部门3、所有链接都以一级目录显示更好的权重4、其他信息扩展,可以增加如:人事招聘,公司介绍,地图,联系我们等5、带有商品和设备的搜索功能6、模板动态化方便扩展模板7、简体繁体选择显示运行环境:windows 2003或者更高windows服务
AssemblyDependencyResolver 能自动读取 .deps.json 文件(发布时生成),定位依赖路径:
- 只在 .NET Core 3.0+ 可用,需确保目标程序集是通过
dotnet publish输出的 - 构造时传入主程序集路径(不是被加载 DLL 的路径),resolver 才能正确解析依赖树
- 配合自定义
AssemblyLoadContext的Load方法使用,否则依赖仍会 fallback 到默认上下文
var resolver = new AssemblyDependencyResolver(assemblyPath); // 注意:传的是 MyPlugin.deps.json 同级的主程序集路径 var context = new CustomLoadContext(resolver); // 自定义 Load 方法中调用 resolver.ResolveAssemblyToPath(...)
反射调用前务必检查 Assembly.IsDynamic 和目标类型可见性
动态加载后,即使 Assembly 对象存在,也可能因以下原因导致 GetType 返回 null 或 Activator.CreateInstance 失败:
-
asm.IsDynamic为 true → 说明是AssemblyBuilder生成的动态程序集,不能用LoadFrom加载方式获取 - 目标类型是
internal且未用[InternalsVisibleTo]开放给调用方程序集 - 类型位于嵌套命名空间或泛型定义中,
GetType("Name")写法不完整(应为"NS.Outer+Inner`1[[T]]")
建议先遍历 asm.GetTypes() 确认类型是否存在,再用 BindingFlags.NonPublic | BindingFlags.Public 获取构造器。









