C# AssemblyLoadContext是否隔离静态变量?

C# AssemblyLoadContext是否隔离静态变量?,c#,static,.net-assembly,.net-core-3.0,assembly-loading,C#,Static,.net Assembly,.net Core 3.0,Assembly Loading,告诉我们: 程序集可卸载性是AssemblyLoadContext的一项新功能。从API的角度来看,这个新特性基本上是透明的,只需几个新的API即可公开。它允许卸载加载程序上下文,释放实例化类型、静态字段和程序集本身的所有内存。应用程序应该能够通过此机制永远加载和卸载程序集,而不会发生内存泄漏 此外,这还提到了“静力学” 我尝试过这个简单的测试: static void Main() { Proxy.X = 15; var alc = new AssemblyLoadContex

告诉我们:

程序集可卸载性是AssemblyLoadContext的一项新功能。从API的角度来看,这个新特性基本上是透明的,只需几个新的API即可公开。它允许卸载加载程序上下文,释放实例化类型、静态字段和程序集本身的所有内存。应用程序应该能够通过此机制永远加载和卸载程序集,而不会发生内存泄漏

此外,这还提到了“静力学”

我尝试过这个简单的测试:

static void Main()
{
    Proxy.X = 15;
    var alc = new AssemblyLoadContext("MyTest", true);
    var asm = alc.LoadFromAssemblyName(typeof(Program).Assembly.GetName());
    var proxy = (Proxy)asm.CreateInstance(typeof(Proxy).FullName);
    Console.WriteLine(proxy.Increment());
}

class Proxy
{
    public static int X;
    public int Increment() => ++X;
}
它输出“16”,这意味着隔离不起作用

我的目标是单元测试可以抛出异常的类静态成员。通常的测试可以通过触发类型初始值设定项来影响彼此的行为,所以我需要以最便宜的方式隔离它们。测试应该在.NETCore3.0上运行


这是正确的方法吗,并且可以
AssemblyLoadContext
提供帮助吗?

是的,它确实隔离了静态变量

如果我们看一下,我们会看到这样的补充:

LoadFromAssemblyName

此方法可用于将程序集加载到中 与当前服务器的加载上下文不同的加载上下文 正在执行程序集。程序集将加载到加载上下文中 在其上调用方法。如果上下文无法解析 在其加载方法中,装配加载将遵循 默认值加载上下文。在这种情况下,可能会加载程序集 来自默认上下文,即使在 非默认上下文

直接在AssemblyLoadContext上调用此方法。默认值将 仅从默认上下文加载程序集。取决于 调用方默认值可能与加载上下文不同,也可能不不同 当前正在执行的程序集的

此方法不会“强制”将程序集加载到指定的 上下文它基本上会启动到指定程序集名称的绑定 在指定的上下文上。该绑定操作将完成整个过程 绑定解析逻辑,可从中自由解析程序集 任何情况下(实际上,最有可能的结果是 指定的上下文或默认上下文)。描述了该过程 上面

确保将指定的程序集加载到指定的加载中 上下文调用AssemblyLoadContext.LoadFromAssemblyPath
并指定 程序集文件的路径

这有点令人沮丧,因为现在我需要确定要加载的程序集的确切位置(没有简单的方法“克隆”已加载的程序集)

该代码工作(输出“1”):

(注意,现在我们不能强制转换到
Proxy
类,因为它与
Proxy
变量的运行时类不同,即使是同一个类……)

static void Main()
{
    Proxy.X = 15;
    var alc = new AssemblyLoadContext("MyTest", true);
    var asm = alc.LoadFromAssemblyPath(typeof(Program).Assembly.Location);
    var proxy = asm.CreateInstance(typeof(Proxy).FullName);
    Console.WriteLine(proxy.GetType().GetMethod("Increment").Invoke(null, null));
}

class Proxy
{
    public static int X;
    public static int Increment() => ++X;
}