1111using System . Reflection ;
1212using System . Runtime . InteropServices ;
1313using System . Runtime . Loader ;
14+ using System . Xml . Linq ;
1415using TestCentric . Metadata ;
1516
1617namespace NUnit . Engine . Internal
@@ -20,13 +21,20 @@ internal sealed class TestAssemblyResolver : IDisposable
2021 private static readonly Logger log = InternalTrace . GetLogger ( typeof ( TestAssemblyResolver ) ) ;
2122
2223 private readonly AssemblyLoadContext _loadContext ;
24+ private readonly string _basePath ;
25+ private readonly AssemblyDependencyResolver _assemblyDependencyResolver ;
2326
2427 // Our Strategies for resolving references
2528 List < ResolutionStrategy > ResolutionStrategies ;
2629
2730 public TestAssemblyResolver ( AssemblyLoadContext loadContext , string testAssemblyPath )
2831 {
2932 _loadContext = loadContext ;
33+ _basePath = Path . GetDirectoryName ( testAssemblyPath ) ;
34+ _assemblyDependencyResolver = new AssemblyDependencyResolver ( testAssemblyPath ) ;
35+ #if NET8_0_OR_GREATER
36+ AppContext . SetData ( "APP_CONTEXT_BASE_DIRECTORY" , _basePath ) ;
37+ #endif
3038
3139 InitializeResolutionStrategies ( loadContext , testAssemblyPath ) ;
3240
@@ -73,19 +81,48 @@ public void Dispose()
7381 _loadContext . Resolving -= OnResolving ;
7482 }
7583
76- public Assembly Resolve ( AssemblyLoadContext context , AssemblyName assemblyName )
77- {
78- return OnResolving ( context , assemblyName ) ;
79- }
84+ // public Assembly Resolve(AssemblyLoadContext context, AssemblyName assemblyName)
85+ // {
86+ // return OnResolving(context, assemblyName);
87+ // }
8088
8189 private Assembly OnResolving ( AssemblyLoadContext loadContext , AssemblyName assemblyName )
8290 {
8391 if ( loadContext == null ) throw new ArgumentNullException ( "context" ) ;
8492
93+ //var runtimeResolverPath = _assemblyDependencyResolver.ResolveAssemblyToPath(assemblyName);
94+ //if (!string.IsNullOrEmpty(runtimeResolverPath) && File.Exists(runtimeResolverPath))
95+ //{
96+ // var loadedAssembly = _loadContext.LoadFromAssemblyPath(runtimeResolverPath);
97+ // if (loadedAssembly != null)
98+ // {
99+ // log.Info($"Assembly {assemblyName} ({loadedAssembly}) is loaded using the deps.json info");
100+ // return loadedAssembly;
101+ // }
102+ //}
103+
85104 foreach ( var strategy in ResolutionStrategies )
86105 if ( strategy . TryToResolve ( loadContext , assemblyName , out Assembly loadedAssembly ) )
87106 return loadedAssembly ;
88107
108+ // Load assemblies that are dependencies, and in the same folder as the test assembly,
109+ // but are not fully specified in test assembly deps.json file. This happens when the
110+ // dependencies reference in the csproj file has CopyLocal=false, and for example, the
111+ // reference is a projectReference and has the same output directory as the parent.
112+ foreach ( var extension in new string [ ] { ".dll" , ".exe" } )
113+ {
114+ string assemblyPath = Path . Combine ( _basePath , assemblyName . Name + extension ) ;
115+ if ( File . Exists ( assemblyPath ) )
116+ {
117+ var loadedAssembly = _loadContext . LoadFromAssemblyPath ( assemblyPath ) ;
118+ if ( loadedAssembly != null )
119+ {
120+ log . Info ( $ "Assembly { assemblyName . Name } ({ assemblyPath } ) is loaded using base path") ;
121+ return loadedAssembly ;
122+ }
123+ }
124+ }
125+
89126 log . Info ( "Cannot resolve assembly '{0}'" , assemblyName ) ;
90127 return null ;
91128 }
0 commit comments