1- // Copyright (c) .NET Foundation. All rights reserved.
1+ // Copyright (c) .NET Foundation. All rights reserved.
22// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33
44using System ;
@@ -66,7 +66,7 @@ internal static IReadOnlyList<Assembly> GetRelatedAssemblies(
6666
6767 // MVC will specifically look for related parts in the same physical directory as the assembly.
6868 // No-op if the assembly does not have a location.
69- if ( assembly . IsDynamic || string . IsNullOrEmpty ( assembly . Location ) )
69+ if ( assembly . IsDynamic )
7070 {
7171 return Array . Empty < Assembly > ( ) ;
7272 }
@@ -78,7 +78,8 @@ internal static IReadOnlyList<Assembly> GetRelatedAssemblies(
7878 }
7979
8080 var assemblyName = assembly . GetName ( ) . Name ;
81- var assemblyLocation = assembly . Location ;
81+ // Assembly.Location may be null for a single-file exe. In this case, attempt to look for related parts in the app's base directory
82+ var assemblyLocation = assembly . Location ?? AppContext . BaseDirectory ;
8283 var assemblyDirectory = Path . GetDirectoryName ( assemblyLocation ) ;
8384
8485 var relatedAssemblies = new List < Assembly > ( ) ;
@@ -91,6 +92,22 @@ internal static IReadOnlyList<Assembly> GetRelatedAssemblies(
9192 Resources . FormatRelatedAssemblyAttribute_AssemblyCannotReferenceSelf ( nameof ( RelatedAssemblyAttribute ) , assemblyName ) ) ;
9293 }
9394
95+ var relatedAssemblyName = new AssemblyName ( attribute . AssemblyFileName ) ;
96+ Assembly relatedAssembly ;
97+ try
98+ {
99+ // Perform a cursory check to determine if the Assembly has already been loaded
100+ // before going to disk. In the ordinary case, related parts that are part of
101+ // application's reference closure should already be loaded.
102+ relatedAssembly = Assembly . Load ( relatedAssemblyName ) ;
103+ relatedAssemblies . Add ( relatedAssembly ) ;
104+ continue ;
105+ }
106+ catch ( IOException )
107+ {
108+ // The assembly isn't already loaded. Patience, we'll attempt to load it from disk next.
109+ }
110+
94111 var relatedAssemblyLocation = Path . Combine ( assemblyDirectory , attribute . AssemblyFileName + ".dll" ) ;
95112 if ( ! fileExists ( relatedAssemblyLocation ) )
96113 {
@@ -106,7 +123,7 @@ internal static IReadOnlyList<Assembly> GetRelatedAssemblies(
106123 }
107124 }
108125
109- var relatedAssembly = loadFile ( relatedAssemblyLocation ) ;
126+ relatedAssembly = loadFile ( relatedAssemblyLocation ) ;
110127 relatedAssemblies . Add ( relatedAssembly ) ;
111128 }
112129
0 commit comments