一, 前世今生
.NET 诞生以来, 程序集的动态加载和卸载都是一个 Hack 的技术, 之前的 NetFx 都是使用 AppDomain 的方式去加载程序集, 然而 AppDomain 并没有提供直接卸载一个程序集的 API, 而是要卸载整个 AppDomain 才能卸载包含在其中的所有程序集. 然而卸载整个 CurrentAppDomain 会使程序不能工作. 可能有人另辟西经, 创建别一个 AppDomain 来加载 / 卸载程序集, 但是由于程序集之间是不能跨域访问的, 也导致只能通过 Remote Proxy 的方式去访问, 这样在类型创建和使用上带来了一定的难度也是类型的继承变得相当复杂.
.NET Core 中一直没有 AppDomain 的支持. 但是在. NET Core 3.0 中, 我最期待的一个特性就是对可收集程序集的支持 (Collectible AssemblyLoadContext). 众所周知. NET Core 中一直使用 AssemblyLoadContext 的 API, 来进行程序集的动态加载, 但是并没有提供 Unload 的方法, 此次升级更新了这方面的能力.
二, AssemblyLoadContext
其实这次 AssemblyLoadContext 的设计, 我认为更像是 Java 中 ClassLoader 的翻版, 可以说非常类似. 在使用过程中自定义 AssemblyLoadContext 可以内部管理其中的程序集, 并对整体 Context 进行 Unload. 使用 AssemblyLoadContext 也可以避免程序集名称和版本的冲突.
三, Getting Started
.NET Core 3.0 还没有正式版, 所有要使用预览版的 SDK 完成以下实例. 我使用的是. NET Core SDK 3.0.100-preview-009812
dotnet new globaljson --sdk-version 3.0.100-preview-009812
AssemblyLoadContext 是一个抽象类的, 我们需要子类化. 下面显示的是我们创建自定义 AssemblyLoadContext 的方法, 实现一个可回收的 Context 需要在构造器中指定 isCollectible: true :
- public class CollectibleAssemblyLoadContext : AssemblyLoadContext
- {
- public CollectibleAssemblyLoadContext() : base(isCollectible: true)
- { }
- protected override Assembly Load(AssemblyName assemblyName)
- {
- return null;
- }
- }
使用 netstandard2.0 创建一个 library
- using System;
- namespace SampleLibrary
- {
- public class SayHello
- {
- public void Hello(int iteration)
- {
- Console.WriteLine($"Hello {iteration}!");
- }
- }
- }
测试 Load/Unload
- var context = new CollectibleAssemblyLoadContext();
- var assemblyPath = Path.Combine(Directory.GetCurrentDirectory(),"SampleLibrary.dll");
- using (var fs = new FileStream(assemblyPath, FileMode.Open, FileAccess.Read))
- {
- var assembly = context.LoadFromStream(fs);
- var type = assembly.GetType("SampleLibrary.SayHello");
- var greetMethod = type.GetMethod("Hello");
- var instance = Activator.CreateInstance(type);
- greetMethod.Invoke(instance, new object[] { i });
- }
- context.Unload();
- GC.Collect();
- GC.WaitForPendingFinalizers();
当执行 GC 收回后, 加载的程序集会被完全的回收.
四, 最后
GitHub: https://github.com/maxzhang1985/YOYOFx 如果觉还可以请 Star 下, 欢迎一起交流.
.NET Core 开源学习群: 214741894
来源: https://www.cnblogs.com/maxzhang1985/p/10875278.html