From 485153dd0b414f71e2432aadc1028afce114e7cf Mon Sep 17 00:00:00 2001 From: svg2003 Date: Sat, 11 Feb 2023 23:44:19 -0800 Subject: [PATCH] fix assembly dependencies resolver for netcore --- .../Internal/TestAssemblyLoadContext.cs | 44 +++++++++++++++---- .../Internal/TestAssemblyResolver.cs | 5 +++ 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/NUnitEngine/nunit.engine.core/Internal/TestAssemblyLoadContext.cs b/src/NUnitEngine/nunit.engine.core/Internal/TestAssemblyLoadContext.cs index bac035bab..69d432fb4 100644 --- a/src/NUnitEngine/nunit.engine.core/Internal/TestAssemblyLoadContext.cs +++ b/src/NUnitEngine/nunit.engine.core/Internal/TestAssemblyLoadContext.cs @@ -15,31 +15,57 @@ internal sealed class TestAssemblyLoadContext : AssemblyLoadContext private readonly string _testAssemblyPath; private readonly string _basePath; private readonly TestAssemblyResolver _resolver; + private readonly System.Runtime.Loader.AssemblyDependencyResolver _runtimeResolver; public TestAssemblyLoadContext(string testAssemblyPath) { _testAssemblyPath = testAssemblyPath; _resolver = new TestAssemblyResolver(this, testAssemblyPath); _basePath = Path.GetDirectoryName(testAssemblyPath); + _runtimeResolver = new AssemblyDependencyResolver(testAssemblyPath); } protected override Assembly Load(AssemblyName name) { var assemblies = AppDomain.CurrentDomain.GetAssemblies(); var loadedAssembly = assemblies.FirstOrDefault(x => x.GetName().Name == name.Name); + if (loadedAssembly != null) + { + return loadedAssembly; + } + + loadedAssembly = base.Load(name); + if (loadedAssembly != null) + { + return loadedAssembly; + } + + var runtimeResolverPath = _runtimeResolver.ResolveAssemblyToPath(name); + if (string.IsNullOrEmpty(runtimeResolverPath) == false && + File.Exists(runtimeResolverPath)) + { + loadedAssembly = LoadFromAssemblyPath(runtimeResolverPath); + } + + if (loadedAssembly != null) + { + return loadedAssembly; + } + loadedAssembly = _resolver.Resolve(this, name); if (loadedAssembly != null) - loadedAssembly = base.Load(name); + { + return loadedAssembly; + } - if (loadedAssembly == null) + // Load assemblies that are dependencies, and in the same folder as the test assembly, + // but are not fully specified in test assembly deps.json file. This happens when the + // dependencies reference in the csproj file has CopyLocal=false, and for example, the + // reference is a projectReference and has the same output directory as the parent. + string assemblyPath = Path.Combine(_basePath, name.Name + ".dll"); + if (File.Exists(assemblyPath)) { - // Load assemblies that are dependencies, and in the same folder as the test assembly, - // but are not fully specified in test assembly deps.json file. This happens when the - // dependencies reference in the csproj file has CopyLocal=false, and for example, the - // reference is a projectReference and has the same output directory as the parent. - string assemblyPath = Path.Combine(_basePath, name.Name + ".dll"); - if (File.Exists(assemblyPath)) - loadedAssembly = LoadFromAssemblyPath(assemblyPath); + loadedAssembly = LoadFromAssemblyPath(assemblyPath); } return loadedAssembly; diff --git a/src/NUnitEngine/nunit.engine.core/Internal/TestAssemblyResolver.cs b/src/NUnitEngine/nunit.engine.core/Internal/TestAssemblyResolver.cs index 6a9624a13..c5c28f4d7 100644 --- a/src/NUnitEngine/nunit.engine.core/Internal/TestAssemblyResolver.cs +++ b/src/NUnitEngine/nunit.engine.core/Internal/TestAssemblyResolver.cs @@ -55,6 +55,11 @@ public void Dispose() _loadContext.Resolving -= OnResolving; } + public Assembly Resolve(AssemblyLoadContext context, AssemblyName name) + { + return OnResolving(context, name); + } + private Assembly OnResolving(AssemblyLoadContext context, AssemblyName name) { foreach (var library in _dependencyContext.RuntimeLibraries)