.Net Core 动态加载和卸载程序集

从 .Net Core 3.0开始支持程序集的加载和卸载,在 .Net FrameWork中使用独立的应用程序域来实现同样的功能,.Net Core 不支持创建多个应用程序域,所以无法使用多个应用程序域来实现程序集动态加载和卸载。

AssemblyLoadContext

程序集加载上下文,它代表一个程序集加载域,在这个域中可以加载、解析、卸载程序集

创建一个 .Net 库项目

cs 复制代码
    public class Class1
    {
        public void Fn1()
        {
            Console.WriteLine("Fn1");
        }

        public void Fn2()
        {
            Console.WriteLine("Fn2");
        }
    }

创建一个控制台项目

实现一个自定义程序集加载上下文类, isCollectible 表示是否支持程序集卸载,默认是 false,所以需要从 AssemblyLoadContext 继承并实现一个AssemblyLoadContext。

cs 复制代码
    internal class MyAssemblyContext:AssemblyLoadContext
    {
        public MyAssemblyContext() : base(isCollectible: true)
        { }
    }

测试加载和卸载方法

cs 复制代码
        //告诉编译器不要内联该方法,防止栈上存在引用导致无法UnLoad。
        [MethodImpl(MethodImplOptions.NoInlining)]
        static void CallLib(string assemblyPath, out WeakReference alcWeakRef)
        {
            MyAssemblyContext mlc = new MyAssemblyContext();

            //加载 assemblyPath 程序集到 MyAssemblyContext 上下文中
            Assembly clib = mlc.LoadFromAssemblyPath(assemblyPath);

            //引用 程序集加载上下文,用于确认当UnLoad时,上下文被正确清理掉了。
            alcWeakRef = new WeakReference(mlc, trackResurrection: true);

            Console.WriteLine("Load ClassLibrary1.dll success");

            Type t= clib.GetType("ClassLibrary1.Class1");
            object obj= Activator.CreateInstance(t);
            t.GetMethod("Fn1").Invoke(obj, new object[] { });

            Console.ReadKey();

            //清理程序集加载上下文并开始卸载该上下文中加载的程序集
            mlc.Unload();

            Console.WriteLine("UnLoad ClassLibrary1.dll success");
        }

测试程序集动态加载和卸载

cs 复制代码
            WeakReference testAlcWeakRef;
            CallLib("E:\\projs\\analyze_dump\\example_net\\net_demo\\ClassLibrary1\\bin\\Debug\\net7.0\\ClassLibrary1.dll",out testAlcWeakRef);

            //显示调用GC清理程序集加载上下文。
            for (int i = 0; testAlcWeakRef.IsAlive && (i < 10); i++)
            {
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }

            Console.ReadKey();

成功加载程序集并实例化程序集中 Class1类并调用Fn1方法

在未卸载程序集前无法删除已加载的dll

卸载程序集后可以正常删除

动态加载和卸载程序集用途

动态更新程序,功能封装到独立的dll库。

应用插件化支持,动态扩展功能。

相关推荐
dephixf18 小时前
工业级部署指南:在西门子IOT2050(Debian 12)上搭建.NET 9.0环境与应用部署
物联网·.netcore·智能制造·边缘网关·西门子·iot 2050
睡前要喝豆奶粉19 小时前
在.NET Core Web Api中使用JWT并配置UserContext获取用户信息
前端·.netcore
睡前要喝豆奶粉19 小时前
在.NET Core Web Api中使用阿里云OSS
阿里云·c#·.netcore
周杰伦fans1 天前
.NET Core WebAPI 中 HTTP 请求方法详解:从新手到精通
网络协议·http·.netcore
睡前要喝豆奶粉3 天前
.NET Core Web API开发需引入的三个基本依赖配置说明
oracle·c#·.netcore
睡前要喝豆奶粉3 天前
.NET Core Web API中数据库相关配置
数据库·c#·.netcore
Archy_Wang_14 天前
Hangfire 入门与实战:在 .NET Core 中实现可靠后台任务处理
c#·.netcore
睡前要喝豆奶粉4 天前
在.NET Core Web Api中使用redis
redis·c#·.netcore
睡前要喝豆奶粉5 天前
多表分页联查——EF Core方式和Dapper方式
c#·.netcore
csdn_aspnet6 天前
.NETCore、.NET 7 和 RabbitMQ 的发布-订阅模式
rabbitmq·.netcore·.net7.