Skip to content

Assembly loading move to AssemblyLoadContext for net8 and higher #1795

@SimonCropp

Description

@SimonCropp

Version 6 changes the assembly loading behavior to using the new AssemblyLoadContext when executing under net8 and higher.

This can have some subtle effects on how types are compared. For example if assemblies are being loaded via Assembly.LoadFrom or AssemblyLoadContext.Default then those assemblies (and the contained types) will not be comparable to the assemblies and types loaded using nunits AssemblyLoadContext.

This will often manifest in plugin based frameworks where assemblies on disk as scanned for known types

For example the below will pass on version 5.2 but fail on version 6.0

var assembly = Assembly.LoadFrom(file);
var type = assembly.GetType("Class1");
ClassicAssert.IsTrue(typeof(Class1) == type);

The fix is to move assembly loading over to using either:

  • nunits AssemblyLoadContext:
// can be cached statically
var context = AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly())!;
var assembly = context.LoadFromAssemblyPath(file);
var name = AssemblyName.GetAssemblyName(file);
var assembly = Assembly.Load(name);

Tests

//All these work on V5.2
[TestFixture]
public class Tests
{
    string file = Path.GetFullPath("ClassLibrary.dll");

    //fails on 6.0
    [Test]
    public void WithLoadFrom()
    {
        var assembly = Assembly.LoadFrom(file);
        var type = assembly.GetType("Class1");
        ClassicAssert.IsTrue(typeof(Class1) == type);
    }

    [Test]
    public void WithGetAssemblyName()
    {
        var name = AssemblyName.GetAssemblyName(file);
        var assembly = Assembly.Load(name);
        var type = assembly.GetType("Class1");
        ClassicAssert.IsTrue(typeof(Class1) == type);
    }

    [Test]
    public void WithGetLoadContext()
    {
        var context = AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly())!;
        var assembly = context.LoadFromAssemblyPath(file);
        var type = assembly.GetType("Class1");
        ClassicAssert.IsTrue(typeof(Class1) == type);
    }

    //fails on 6.0
    [Test]
    public void WithDefaultContext()
    {
        var context = AssemblyLoadContext.Default!;
        var assembly = context.LoadFromAssemblyPath(file);
        var type = assembly.GetType("Class1");
        ClassicAssert.IsTrue(typeof(Class1) == type);
    }
}

Full Repro

https://github.com/SimonCropp/NunitAdaptorAssemblyLoadingRepro

Metadata

Metadata

Assignees

Labels

BugV3All issues related to V3

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions