@@ -13,6 +13,8 @@ namespace Brutal.Dev.StrongNameSigner
1313 [ Serializable ]
1414 public sealed class AssemblyInfo : IEquatable < AssemblyInfo > , IDisposable
1515 {
16+ private static DefaultAssemblyResolver assemblyResolver = null ;
17+
1618 private readonly Lazy < AssemblyDefinition > modifiedDefinition ;
1719
1820 private bool isDisposed ;
@@ -216,128 +218,154 @@ private static string GetDotNetVersion(TargetRuntime runtime)
216218
217219 private static ReaderParameters GetReadParameters ( string assemblyPath , string [ ] probingPaths )
218220 {
219- var resolver = new DefaultAssemblyResolver ( ) ;
221+ var usingCachedResolver = assemblyResolver is not null ;
222+ assemblyResolver ??= new DefaultAssemblyResolver ( ) ;
223+
220224 if ( ! string . IsNullOrEmpty ( assemblyPath ) && File . Exists ( assemblyPath ) )
221225 {
222- resolver . RemoveSearchDirectory ( Path . GetDirectoryName ( assemblyPath ) ) ;
223- resolver . AddSearchDirectory ( Path . GetDirectoryName ( assemblyPath ) ) ;
226+ assemblyResolver . RemoveSearchDirectory ( Path . GetDirectoryName ( assemblyPath ) ) ;
227+ assemblyResolver . AddSearchDirectory ( Path . GetDirectoryName ( assemblyPath ) ) ;
224228 }
225229
226230 if ( probingPaths is not null )
227231 {
228232 foreach ( var searchDir in probingPaths . Where ( Directory . Exists ) )
229233 {
230- resolver . RemoveSearchDirectory ( searchDir ) ;
231- resolver . AddSearchDirectory ( searchDir ) ;
234+ assemblyResolver . RemoveSearchDirectory ( searchDir ) ;
235+ assemblyResolver . AddSearchDirectory ( searchDir ) ;
232236 }
233237 }
234238
235- // 1. Application base directory.
236- resolver . RemoveSearchDirectory ( AppDomain . CurrentDomain . BaseDirectory ) ;
237- resolver . AddSearchDirectory ( AppDomain . CurrentDomain . BaseDirectory ) ;
238-
239+ if ( ! usingCachedResolver )
240+ {
241+ // 1. Application base directory.
242+ assemblyResolver . RemoveSearchDirectory ( AppDomain . CurrentDomain . BaseDirectory ) ;
243+ assemblyResolver . AddSearchDirectory ( AppDomain . CurrentDomain . BaseDirectory ) ;
239244
240- // 2. .NET Core/5+ reference assemblies.
241- var dotnetRoot = Environment . GetEnvironmentVariable ( "DOTNET_ROOT" ) ??
242- Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . ProgramFiles ) , "dotnet" ) ;
245+ // 2. .NET Core/5+ reference assemblies.
246+ var dotnetRoot = Environment . GetEnvironmentVariable ( "DOTNET_ROOT" ) ??
247+ Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . ProgramFiles ) , "dotnet" ) ;
243248
244- if ( Directory . Exists ( dotnetRoot ) )
245- {
246- // Packs directory for .NET Core/5+ reference assemblies.
247- var packsDir = Path . Combine ( dotnetRoot , "packs" , "Microsoft.NETCore.App.Ref" ) ;
248- if ( Directory . Exists ( packsDir ) )
249+ if ( Directory . Exists ( dotnetRoot ) )
249250 {
250- var latestVersion = Directory . GetDirectories ( packsDir )
251- . Select ( d => new DirectoryInfo ( d ) . Name )
252- . OrderByDescending ( v => v )
253- . FirstOrDefault ( ) ;
251+ // Packs directory for .NET Core/5+ reference assemblies.
252+ var packsDir = Path . Combine ( dotnetRoot , "packs" ) ;
253+ var packsRefDir = Path . Combine ( packsDir , "Microsoft.NETCore.App.Ref" ) ;
254+ if ( Directory . Exists ( packsRefDir ) )
255+ {
256+ var latestVersion = Directory . EnumerateDirectories ( packsRefDir )
257+ . Select ( d => new DirectoryInfo ( d ) . Name )
258+ . OrderByDescending ( v => v )
259+ . FirstOrDefault ( ) ;
260+
261+ if ( latestVersion is not null )
262+ {
263+ var majorMinorVersion = latestVersion . Split ( '.' ) . Take ( 2 ) . Aggregate ( ( a , b ) => $ "{ a } .{ b } ") ;
264+ foreach ( var dirToSearch in Directory . EnumerateDirectories ( packsDir , "*" , SearchOption . AllDirectories )
265+ . Where ( d => d . EndsWith ( Path . Combine ( ".Ref" , latestVersion , "ref" , $ "net{ majorMinorVersion } ") ) ) )
266+ {
267+ assemblyResolver . RemoveSearchDirectory ( dirToSearch ) ;
268+ assemblyResolver . AddSearchDirectory ( dirToSearch ) ;
269+ }
270+ }
271+ }
254272
255- if ( latestVersion is not null )
273+ // Shared framework.
274+ var sharedDir = Path . Combine ( dotnetRoot , "shared" ) ;
275+ var sharedAppDir = Path . Combine ( sharedDir , "Microsoft.NETCore.App" ) ;
276+ if ( Directory . Exists ( sharedAppDir ) )
256277 {
257- var majorMinorVersion = latestVersion . Split ( '.' ) . Take ( 2 ) . Aggregate ( ( a , b ) => $ "{ a } .{ b } ") ;
258- var dirToSearch = Path . Combine ( packsDir , latestVersion , "ref" , $ "net{ majorMinorVersion } ") ;
259- resolver . RemoveSearchDirectory ( dirToSearch ) ;
260- resolver . AddSearchDirectory ( dirToSearch ) ;
278+ var latestVersion = Directory . EnumerateDirectories ( sharedAppDir )
279+ . Select ( d => new DirectoryInfo ( d ) . Name )
280+ . OrderByDescending ( v => v )
281+ . FirstOrDefault ( ) ;
282+
283+ if ( latestVersion is not null )
284+ {
285+ foreach ( var dirToSearch in Directory . EnumerateDirectories ( sharedDir , "*" , SearchOption . AllDirectories )
286+ . Where ( d => d . EndsWith ( Path . Combine ( ".App" , latestVersion ) ) ) )
287+ {
288+ assemblyResolver . RemoveSearchDirectory ( dirToSearch ) ;
289+ assemblyResolver . AddSearchDirectory ( dirToSearch ) ;
290+ }
291+ }
261292 }
262293 }
263294
264- // Shared framework.
265- var sharedDir = Path . Combine ( dotnetRoot , "shared" , "Microsoft.NETCore.App" ) ;
266- if ( Directory . Exists ( sharedDir ) )
295+ // 3. Reference assemblies for different frameworks.
296+ var refAssembliesDir = Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . ProgramFilesX86 ) , "Reference Assemblies" , "Microsoft" , "Framework" ) ;
297+
298+ // .NET Standard reference assemblies.
299+ var netStandardRef = Path . Combine ( refAssembliesDir , ".NETStandard" ) ;
300+ if ( Directory . Exists ( netStandardRef ) )
267301 {
268- var latestVersion = Directory . GetDirectories ( sharedDir )
269- . Select ( d => new DirectoryInfo ( d ) . Name )
270- . OrderByDescending ( v => v )
302+ var latestStandard = Directory . EnumerateDirectories ( netStandardRef )
303+ . OrderByDescending ( d => d )
271304 . FirstOrDefault ( ) ;
272305
273- if ( latestVersion is not null )
306+ if ( latestStandard is not null )
274307 {
275- var dirToSearch = Path . Combine ( sharedDir , latestVersion ) ;
276- resolver . RemoveSearchDirectory ( dirToSearch ) ;
277- resolver . AddSearchDirectory ( dirToSearch ) ;
308+ var dirToSearch = Path . Combine ( latestStandard , "ref" ) ;
309+ assemblyResolver . RemoveSearchDirectory ( dirToSearch ) ;
310+ assemblyResolver . AddSearchDirectory ( dirToSearch ) ;
278311 }
279312 }
280- }
281313
282- // 3. Reference assemblies for different frameworks.
283- var refAssembliesDir = Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . ProgramFilesX86 ) , "Reference Assemblies" , "Microsoft" , "Framework" ) ;
284-
285- // .NET Standard reference assemblies.
286- var netStandardRef = Path . Combine ( refAssembliesDir , ".NETStandard" ) ;
287- if ( Directory . Exists ( netStandardRef ) )
288- {
289- var latestStandard = Directory . GetDirectories ( netStandardRef )
290- . OrderByDescending ( d => d )
291- . FirstOrDefault ( ) ;
314+ // .NET Framework reference assemblies.
315+ foreach ( var version in new [ ] { "v4.8" , "v4.7.2" , "v4.7.1" , "v4.7" , "v4.6.2" , "v4.6.1" , "v4.6" } )
316+ {
317+ var frameworkRefDir = Path . Combine ( refAssembliesDir , ".NETFramework" , version ) ;
318+ if ( Directory . Exists ( frameworkRefDir ) )
319+ {
320+ assemblyResolver . RemoveSearchDirectory ( frameworkRefDir ) ;
321+ assemblyResolver . AddSearchDirectory ( frameworkRefDir ) ;
322+ break ; // Use the first available.
323+ }
324+ }
292325
293- if ( latestStandard is not null )
326+ // 4. Current runtime directory.
327+ var runtimeDir = Path . GetDirectoryName ( typeof ( object ) . Assembly . Location ) ;
328+ if ( ! string . IsNullOrEmpty ( runtimeDir ) )
294329 {
295- var dirToSearch = Path . Combine ( latestStandard , "ref" ) ;
296- resolver . RemoveSearchDirectory ( dirToSearch ) ;
297- resolver . AddSearchDirectory ( dirToSearch ) ;
330+ var dirToSearch = runtimeDir . TrimEnd ( Path . DirectorySeparatorChar ) ;
331+ assemblyResolver . RemoveSearchDirectory ( dirToSearch ) ;
332+ assemblyResolver . AddSearchDirectory ( dirToSearch ) ;
298333 }
299- }
300334
301- // .NET Framework reference assemblies.
302- foreach ( var version in new [ ] { "v4.8" , "v4.7.2" , "v4.7.1" , "v4.7" , "v4.6.2" , "v4.6.1" , "v4.6" } )
303- {
304- var frameworkRefDir = Path . Combine ( refAssembliesDir , ".NETFramework" , version ) ;
305- if ( Directory . Exists ( frameworkRefDir ) )
335+ // 5. .NET Framework runtime.
336+ try
306337 {
307- resolver . RemoveSearchDirectory ( frameworkRefDir ) ;
308- resolver . AddSearchDirectory ( frameworkRefDir ) ;
309- break ; // Use the first available.
338+ var frameworkDir = RuntimeEnvironment . GetRuntimeDirectory ( ) ;
339+ if ( Directory . Exists ( frameworkDir ) )
340+ {
341+ var dirToSearch = frameworkDir . TrimEnd ( Path . DirectorySeparatorChar ) ;
342+ assemblyResolver . RemoveSearchDirectory ( dirToSearch ) ;
343+ assemblyResolver . AddSearchDirectory ( dirToSearch ) ;
344+ }
310345 }
311- }
346+ catch { /* Ignore if not available */ }
312347
313- // 4. Current runtime directory.
314- var runtimeDir = Path . GetDirectoryName ( typeof ( object ) . Assembly . Location ) ;
315- if ( ! string . IsNullOrEmpty ( runtimeDir ) )
316- {
317- var dirToSearch = runtimeDir . TrimEnd ( Path . DirectorySeparatorChar ) ;
318- resolver . RemoveSearchDirectory ( dirToSearch ) ;
319- resolver . AddSearchDirectory ( dirToSearch ) ;
320- }
348+ // 6. Add the NuGet pacakges directotry.
349+ var nugetPackagesPath = Environment . GetEnvironmentVariable ( "NUGET_PACKAGES" ) ??
350+ Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . UserProfile ) , ".nuget" , "packages" ) ;
321351
322- // 5. .NET Framework runtime.
323- try
324- {
325- var frameworkDir = RuntimeEnvironment . GetRuntimeDirectory ( ) ;
326- if ( Directory . Exists ( frameworkDir ) )
352+ if ( Directory . Exists ( nugetPackagesPath ) )
327353 {
328- var dirToSearch = frameworkDir . TrimEnd ( Path . DirectorySeparatorChar ) ;
329- resolver . RemoveSearchDirectory ( dirToSearch ) ;
330- resolver . AddSearchDirectory ( dirToSearch ) ;
354+ foreach ( var dirToSearch in Directory . EnumerateDirectories ( nugetPackagesPath , "*" , SearchOption . AllDirectories )
355+ . Where ( d => d . Contains ( $ "{ Path . DirectorySeparatorChar } lib{ Path . DirectorySeparatorChar } net") ) )
356+ {
357+ assemblyResolver . RemoveSearchDirectory ( dirToSearch ) ;
358+ assemblyResolver . AddSearchDirectory ( dirToSearch ) ;
359+ }
331360 }
332- }
333- catch { /* Ignore if not available */ }
334361
335- // Add other well known locations.
336- resolver . RemoveSearchDirectory ( Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . Windows ) , "Microsoft.NET" , "assembly" ) ) ;
337- resolver . RemoveSearchDirectory ( Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . Windows ) , "assembly" ) ) ;
362+ // Add other well known locations.
363+ assemblyResolver . RemoveSearchDirectory ( Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . Windows ) , "Microsoft.NET" , "assembly" ) ) ;
364+ assemblyResolver . RemoveSearchDirectory ( Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . Windows ) , "assembly" ) ) ;
338365
339- resolver . AddSearchDirectory ( Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . Windows ) , "Microsoft.NET" , "assembly" ) ) ;
340- resolver . AddSearchDirectory ( Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . Windows ) , "assembly" ) ) ;
366+ assemblyResolver . AddSearchDirectory ( Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . Windows ) , "Microsoft.NET" , "assembly" ) ) ;
367+ assemblyResolver . AddSearchDirectory ( Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . Windows ) , "assembly" ) ) ;
368+ }
341369
342370 ReaderParameters readParams ;
343371
@@ -347,8 +375,8 @@ private static ReaderParameters GetReadParameters(string assemblyPath, string[]
347375 {
348376 InMemory = true ,
349377 ReadingMode = ReadingMode . Deferred ,
350- AssemblyResolver = resolver ,
351- MetadataResolver = new MetadataResolver ( resolver ) ,
378+ AssemblyResolver = assemblyResolver ,
379+ MetadataResolver = new MetadataResolver ( assemblyResolver ) ,
352380 ReadSymbols = File . Exists ( Path . ChangeExtension ( assemblyPath , ".pdb" ) ) ,
353381 } ;
354382 }
@@ -358,8 +386,8 @@ private static ReaderParameters GetReadParameters(string assemblyPath, string[]
358386 {
359387 InMemory = true ,
360388 ReadingMode = ReadingMode . Deferred ,
361- AssemblyResolver = resolver ,
362- MetadataResolver = new MetadataResolver ( resolver ) ,
389+ AssemblyResolver = assemblyResolver ,
390+ MetadataResolver = new MetadataResolver ( assemblyResolver ) ,
363391 } ;
364392 }
365393
0 commit comments