@@ -414,30 +414,37 @@ public void LoadResolverAssembly_MSBuildSdkResolver_WithAndWithoutFallback(bool
414414
415415 var assemblyFile = Path . Combine ( resolverFolder , "Microsoft.DotNet.MSBuildSdkResolver.dll" ) ;
416416
417+ // Create file based on test scenario
417418 if ( shouldSucceed )
418419 {
419- // For fallback test: create a valid assembly file
420- var sourceAssembly = typeof ( SdkResolverLoader ) . Assembly ;
421- File . Copy ( sourceAssembly . Location , assemblyFile , true ) ;
420+ // For fallback test: copy test assembly (which is already loaded) instead of Microsoft.Build.dll
421+ // This reduces side effects because the test assembly is already in the load context
422+ var testAssembly = typeof ( SdkResolverLoader_Tests ) . Assembly ;
423+ File . Copy ( testAssembly . Location , assemblyFile , true ) ;
422424 }
423425 else
424426 {
425427 // For no-fallback test: create invalid assembly content to force Assembly.Load to fail
426428 File . WriteAllText ( assemblyFile , "invalid assembly content" ) ;
427429 }
428430
429- // Use MockSdkResolverLoader to simulate behavior without modifying global state
431+ // Use MockSdkResolverLoader to test actual Assembly.LoadFrom behavior
432+ // but with test assembly (already loaded) instead of Microsoft.Build.dll to reduce side effects
430433 var loader = new MockSdkResolverLoader
431434 {
432435 FindPotentialSdkResolversFunc = ( _ , __ ) => new List < string > { assemblyFile } ,
436+ GetResolverTypesFunc = assembly => new [ ] { typeof ( MockSdkResolverWithAssemblyPath ) } ,
433437 LoadResolverAssemblyFunc = ( resolverPath ) =>
434438 {
435439 string resolverFileName = Path . GetFileNameWithoutExtension ( resolverPath ) ;
436440 if ( resolverFileName . Equals ( "Microsoft.DotNet.MSBuildSdkResolver" , StringComparison . OrdinalIgnoreCase ) )
437441 {
438- if ( isRunningInVS )
442+ // Capture test parameters via closure
443+ bool simulatedIsRunningInVS = isRunningInVS ;
444+
445+ if ( simulatedIsRunningInVS )
439446 {
440- // Simulate VS: use Assembly.Load directly, no fallback
447+ // VS behavior: try Assembly.Load directly, no fallback
441448 AssemblyName assemblyName = new AssemblyName ( resolverFileName )
442449 {
443450 CodeBase = resolverPath ,
@@ -447,8 +454,23 @@ public void LoadResolverAssembly_MSBuildSdkResolver_WithAndWithoutFallback(bool
447454 }
448455 else
449456 {
450- // Simulate non-VS: try Assembly.Load first, fallback to LoadFrom if it fails
451- return Assembly . LoadFrom ( resolverPath ) ;
457+ // Non-VS behavior: try Assembly.Load first, fallback to LoadFrom if it fails
458+ // We actually call Assembly.LoadFrom here but with test assembly (already loaded)
459+ // to reduce side effects compared to loading Microsoft.Build.dll copy
460+ try
461+ {
462+ // Try Assembly.Load first (will fail for invalid file, succeed for valid)
463+ AssemblyName assemblyName = new AssemblyName ( resolverFileName )
464+ {
465+ CodeBase = resolverPath ,
466+ } ;
467+ return Assembly . Load ( assemblyName ) ;
468+ }
469+ catch ( Exception )
470+ {
471+ // Fallback to LoadFrom
472+ return Assembly . LoadFrom ( resolverPath ) ;
473+ }
452474 }
453475 }
454476 return Assembly . LoadFrom ( resolverPath ) ;
@@ -515,7 +537,13 @@ private sealed class MockSdkResolverWithAssemblyPath : SdkResolverBase
515537 {
516538 public string AssemblyPath ;
517539
518- public MockSdkResolverWithAssemblyPath ( string assemblyPath = "" )
540+ // Parameterless constructor for reflection-based instantiation
541+ public MockSdkResolverWithAssemblyPath ( )
542+ : this ( "" )
543+ {
544+ }
545+
546+ public MockSdkResolverWithAssemblyPath ( string assemblyPath )
519547 {
520548 AssemblyPath = assemblyPath ;
521549 }
0 commit comments