Skip to content

Commit 39c6fb8

Browse files
committed
Start to use ALC
1 parent 95d7c54 commit 39c6fb8

File tree

2 files changed

+26
-27
lines changed

2 files changed

+26
-27
lines changed

Core/Data/TestProjectData.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
35
using System.Reflection;
6+
using System.Runtime.Loader;
47
using System.Text;
58
using TestMyCode.CSharp.API.Attributes;
69

@@ -21,9 +24,23 @@ public TestProjectData()
2124

2225
public void LoadProject(string assemblyPath)
2326
{
24-
//I would prefer using AssemblyLoadContext but then xUnit can't find the assembly
25-
//xUnit only accepts assembly location and not the assembly itself
26-
Assembly assembly = Assembly.LoadFrom(assemblyPath);
27+
AssemblyLoadContext alc = new AssemblyLoadContext("TestProjectLoader", isCollectible: true);
28+
29+
alc.Resolving += (sender, args) =>
30+
{
31+
string assemblyName = $"{args.Name}.dll";
32+
string dir = Path.GetDirectoryName(assemblyPath)!;
33+
34+
string assemblyFile = Path.Combine(dir, assemblyName);
35+
if (File.Exists(assemblyFile))
36+
{
37+
return sender.LoadFromAssemblyPath(assemblyFile);
38+
}
39+
40+
return null;
41+
};
42+
43+
Assembly assembly = alc.LoadFromAssemblyPath(assemblyPath);
2744

2845
this.LoadAssembly(assembly);
2946
}

Core/Test/ProjectTestRunner.cs

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.IO;
44
using System.Reflection;
55
using System.Runtime.CompilerServices;
6+
using System.Runtime.Loader;
67
using System.Text;
78
using System.Threading;
89
using TestMyCode.CSharp.Core.Data;
@@ -33,10 +34,10 @@ public void RunAssemblies(IReadOnlyList<Assembly> assemblies)
3334

3435
public void RunAssemblyTests(Assembly assembly)
3536
{
36-
using ManualResetEvent testsCompled = new ManualResetEvent(false);
37-
using AssemblyRunner runner = AssemblyRunner.WithoutAppDomain(assembly.Location);
37+
using AssemblyLoadContext.ContextualReflectionScope scope = AssemblyLoadContext.EnterContextualReflection(assembly);
3838

39-
AppDomain.CurrentDomain.AssemblyResolve += this.CreateTestAssemblyResolver(assembly);
39+
using ManualResetEvent testsCompleted = new ManualResetEvent(false);
40+
using AssemblyRunner runner = AssemblyRunner.WithoutAppDomain(assembly.Location);
4041

4142
runner.OnTestFailed += info =>
4243
{
@@ -52,39 +53,20 @@ public void RunAssemblyTests(Assembly assembly)
5253

5354
runner.OnExecutionComplete += info =>
5455
{
55-
testsCompled.Set();
56+
testsCompleted.Set();
5657
};
5758

5859
//This is non blocking call!
5960
runner.Start();
6061

6162
//We don't want to exit before all of the tests have ran
6263
//This will be signaled once all of the tests have been ran
63-
testsCompled.WaitOne();
64+
testsCompleted.WaitOne();
6465

6566
//OnExecutionComplete is invoked before setting the Status so spin here until it changes
6667
SpinWait.SpinUntil(() => runner.Status == AssemblyRunnerStatus.Idle);
6768
}
6869

69-
private ResolveEventHandler CreateTestAssemblyResolver(Assembly assembly)
70-
{
71-
return (sender, args) =>
72-
{
73-
AssemblyName name = new AssemblyName(args.Name!);
74-
75-
string assemblyName = $"{name.Name}.dll";
76-
string dir = Path.GetDirectoryName(assembly.Location)!;
77-
78-
string assemblyFile = Path.Combine(dir, assemblyName);
79-
if (File.Exists(assemblyFile))
80-
{
81-
return Assembly.LoadFile(assemblyFile);
82-
}
83-
84-
return null;
85-
};
86-
}
87-
8870
private void AddTestResult(MethodTestResult result)
8971
{
9072
//We lock here to ensure that we don't have any race conditions

0 commit comments

Comments
 (0)