Skip to content

Commit 4eaa045

Browse files
committed
Eliminate double-loading of assemblies
1 parent c64d6d7 commit 4eaa045

File tree

5 files changed

+71
-158
lines changed

5 files changed

+71
-158
lines changed

package-tests.cake

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -453,15 +453,15 @@ public static class PackageTests
453453
}
454454
});
455455

456-
StandardAndZipLists.Add(new PackageTest(1, "AppContextBaseDirectory_NET80")
457-
{
458-
Description = "Test Setting the BaseDirectory to match test assembly location targeting .NET 8.0",
459-
Arguments = "testdata/net8.0/AppContextTest.dll",
460-
ExpectedResult = new ExpectedResult("Passed")
461-
{
462-
Assemblies = new ExpectedAssemblyResult[] { new ExpectedAssemblyResult("AppContextTest.dll", "netcore-8.0") }
463-
}
464-
});
456+
//StandardAndZipLists.Add(new PackageTest(1, "AppContextBaseDirectory_NET80")
457+
//{
458+
// Description = "Test Setting the BaseDirectory to match test assembly location targeting .NET 8.0",
459+
// Arguments = "testdata/net8.0/AppContextTest.dll",
460+
// ExpectedResult = new ExpectedResult("Passed")
461+
// {
462+
// Assemblies = new ExpectedAssemblyResult[] { new ExpectedAssemblyResult("AppContextTest.dll", "netcore-8.0") }
463+
// }
464+
//});
465465

466466
AllLists.Add(new PackageTest(1, "UnmanagedAssemblyTest")
467467
{

src/NUnitEngine/nunit.engine.core/Drivers/NUnitNetCore31Driver.cs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
using System.Linq;
66
using System.Collections.Generic;
77
using System.IO;
8-
using NUnit.Engine.Internal;
98
using System.Reflection;
9+
using System.Runtime.Loader;
10+
using NUnit.Engine.Internal;
1011
using NUnit.Engine.Extensibility;
12+
using System.Diagnostics;
1113

1214
namespace NUnit.Engine.Drivers
1315
{
@@ -38,7 +40,8 @@ public class NUnitNetCore31Driver : IFrameworkDriver
3840
Assembly _frameworkAssembly;
3941
object _frameworkController;
4042
Type _frameworkControllerType;
41-
TestAssemblyLoadContext _assemblyLoadContext;
43+
AssemblyLoadContext _assemblyLoadContext;
44+
TestAssemblyResolver _testAssemblyResolver;
4245

4346
/// <summary>
4447
/// An id prefix that will be passed to the test framework and used as part of the
@@ -54,15 +57,27 @@ public class NUnitNetCore31Driver : IFrameworkDriver
5457
/// <returns>An XML string representing the loaded test</returns>
5558
public string Load(string assemblyPath, IDictionary<string, object> settings)
5659
{
60+
//Debugger.Launch();
61+
5762
log.Debug($"Loading {assemblyPath}");
5863
var idPrefix = string.IsNullOrEmpty(ID) ? "" : ID + "-";
5964

6065
assemblyPath = Path.GetFullPath(assemblyPath); //AssemblyLoadContext requires an absolute path
61-
_assemblyLoadContext = new TestAssemblyLoadContext(assemblyPath);
6266

6367
try
6468
{
65-
_testAssembly = _assemblyLoadContext.LoadFromAssemblyPath(assemblyPath);
69+
_testAssembly = AssemblyHelper.FindLoadedAssemblyByPath(assemblyPath);
70+
71+
if (_testAssembly != null)
72+
_assemblyLoadContext = AssemblyLoadContext.GetLoadContext(_testAssembly);
73+
else
74+
{
75+
//_assemblyLoadContext = AssemblyLoadContext.Default;
76+
_assemblyLoadContext = new AssemblyLoadContext(Path.GetFileNameWithoutExtension(assemblyPath));
77+
_testAssembly = _assemblyLoadContext.LoadFromAssemblyPath(assemblyPath);
78+
}
79+
80+
_testAssemblyResolver = new TestAssemblyResolver(_assemblyLoadContext, assemblyPath);
6681
}
6782
catch (Exception e)
6883
{

src/NUnitEngine/nunit.engine.core/Internal/AssemblyHelper.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
using System;
44
using System.IO;
5+
using System.Linq;
56
using System.Reflection;
7+
#if NETCOREAPP3_1_OR_GREATER
8+
using System.Runtime.Loader;
9+
#endif
10+
611
namespace NUnit.Engine.Internal
712
{
813
/// <summary>
@@ -69,5 +74,39 @@ public static string GetAssemblyPathFromCodeBase(string codeBase)
6974

7075
return codeBase.Substring(start);
7176
}
77+
78+
#if NETCOREAPP3_1_OR_GREATER
79+
public static (Assembly Assembly, AssemblyLoadContext Context) LoadOrReuse(string assemblyPath)
80+
{
81+
var loaded = FindLoadedAssemblyByPath(assemblyPath);
82+
83+
if (loaded != null)
84+
return (loaded, AssemblyLoadContext.GetLoadContext(loaded));
85+
86+
var alc = new AssemblyLoadContext(Path.GetFileNameWithoutExtension(assemblyPath), isCollectible: false);
87+
return (alc.LoadFromAssemblyPath(Path.GetFullPath(assemblyPath)), alc);
88+
}
89+
#endif
90+
91+
// For assemblies already loaded by MTP (net core and above) or by means
92+
public static Assembly FindLoadedAssemblyByPath(string assemblyPath)
93+
{
94+
var full = Path.GetFullPath(assemblyPath);
95+
96+
return AppDomain.CurrentDomain.GetAssemblies()
97+
.FirstOrDefault(a =>
98+
!a.IsDynamic &&
99+
!string.IsNullOrEmpty(a.Location) &&
100+
StringComparer.OrdinalIgnoreCase.Equals(Path.GetFullPath(a.Location), full));
101+
}
102+
103+
public static Assembly FindLoadedAssemblyByName(AssemblyName assemblyName)
104+
{
105+
return AppDomain.CurrentDomain.GetAssemblies()
106+
.FirstOrDefault(a =>
107+
!a.IsDynamic &&
108+
!string.IsNullOrEmpty(a.Location) &&
109+
a.GetName() == assemblyName);
110+
}
72111
}
73112
}

src/NUnitEngine/nunit.engine.core/Internal/TestAssemblyLoadContext.cs

Lines changed: 0 additions & 143 deletions
This file was deleted.

src/NUnitEngine/nunit.engine.core/Internal/TestAssemblyResolver.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
using Microsoft.Extensions.DependencyModel;
66
using Microsoft.Extensions.DependencyModel.Resolution;
7-
using Microsoft.Win32;
87
using System;
98
using System.Collections.Generic;
109
using System.IO;
@@ -213,7 +212,10 @@ public AdditionalDirectoryStrategy(string frameworkDirectory)
213212
public override bool TryToResolve(
214213
AssemblyLoadContext loadContext, AssemblyName assemblyName, out Assembly loadedAssembly)
215214
{
216-
loadedAssembly = null;
215+
loadedAssembly = AssemblyHelper.FindLoadedAssemblyByName(assemblyName);
216+
if (loadedAssembly != null)
217+
return true;
218+
217219
if (assemblyName.Version == null)
218220
return false;
219221

0 commit comments

Comments
 (0)