2
2
// Licensed under the MIT License.
3
3
4
4
using System ;
5
+ using System . Collections . Concurrent ;
5
6
using System . Collections . Generic ;
6
7
using System . Diagnostics ;
7
8
using System . Globalization ;
@@ -49,13 +50,13 @@ public sealed class ManagedHost : JSEventEmitter, IDisposable
49
50
/// <summary>
50
51
/// Mapping from assembly file paths to loaded assemblies.
51
52
/// </summary>
52
- private readonly Dictionary < string , Assembly > _loadedAssembliesByPath = new ( ) ;
53
+ private readonly ConcurrentDictionary < string , Assembly ? > _loadedAssembliesByPath = new ( ) ;
53
54
54
55
/// <summary>
55
56
/// Mapping from assembly names (not including version or other parts) to
56
57
/// loaded assemblies.
57
58
/// </summary>
58
- private readonly Dictionary < string , Assembly > _loadedAssembliesByName = new ( ) ;
59
+ private readonly ConcurrentDictionary < string , Assembly > _loadedAssembliesByName = new ( ) ;
59
60
60
61
/// <summary>
61
62
/// Tracks names of assemblies that have been exported to JS.
@@ -467,7 +468,7 @@ public JSValue LoadAssembly(JSCallbackArgs args)
467
468
assembly = LoadAssembly ( assemblyNameOrFilePath , allowNativeLibrary : true ) ;
468
469
}
469
470
470
- if ( ! _exportedAssembliesByName . Contains ( assembly . GetName ( ) . Name ! ) )
471
+ if ( assembly != null && ! _exportedAssembliesByName . Contains ( assembly . GetName ( ) . Name ! ) )
471
472
{
472
473
_typeExporter . ExportAssemblyTypes ( assembly ) ;
473
474
_exportedAssembliesByName . Add ( assembly . GetName ( ) . Name ! ) ;
@@ -487,7 +488,7 @@ private JSValue ResolveAssembly(JSCallbackArgs args)
487
488
return default ;
488
489
}
489
490
490
- private Assembly LoadAssembly ( string assemblyNameOrFilePath , bool allowNativeLibrary )
491
+ private Assembly ? LoadAssembly ( string assemblyNameOrFilePath , bool allowNativeLibrary )
491
492
{
492
493
Trace ( $ "> ManagedHost.LoadAssembly({ assemblyNameOrFilePath } )") ;
493
494
@@ -525,41 +526,44 @@ private Assembly LoadAssembly(string assemblyNameOrFilePath, bool allowNativeLib
525
526
"or the name of a system assembly (without path or DLL extension)." ) ;
526
527
}
527
528
528
- Assembly assembly ;
529
- try
529
+ Assembly ? assembly = _loadedAssembliesByPath . GetOrAdd ( assemblyFilePath , _ =>
530
530
{
531
+ try
532
+ {
531
533
#if NETFRAMEWORK || NETSTANDARD
532
- // TODO: Load assemblies in a separate appdomain.
533
- assembly = Assembly . LoadFrom ( assemblyFilePath ) ;
534
+ // TODO: Load assemblies in a separate appdomain.
535
+ return Assembly . LoadFrom ( assemblyFilePath ) ;
534
536
#else
535
- assembly = _loadContext . LoadFromAssemblyPath ( assemblyFilePath ) ;
537
+ return _loadContext . LoadFromAssemblyPath ( assemblyFilePath ) ;
536
538
#endif
537
- }
538
- catch ( BadImageFormatException )
539
- {
540
- if ( ! allowNativeLibrary )
541
- {
542
- throw ;
543
539
}
540
+ catch ( BadImageFormatException )
541
+ {
542
+ if ( ! allowNativeLibrary )
543
+ {
544
+ throw ;
545
+ }
544
546
545
- // This might be a native DLL, not a managed assembly.
546
- // Load the native library, which enables it to be auto-resolved by
547
- // any later DllImport operations for the same library name.
548
- NativeLibrary . Load ( assemblyFilePath ) ;
547
+ // This might be a native DLL, not a managed assembly.
548
+ // Load the native library, which enables it to be auto-resolved by
549
+ // any later DllImport operations for the same library name.
550
+ NativeLibrary . Load ( assemblyFilePath ) ;
551
+ return null ;
552
+ }
553
+ catch ( FileNotFoundException fnfex )
554
+ {
555
+ throw new FileNotFoundException (
556
+ $ "Assembly file not found: { assemblyNameOrFilePath } ", fnfex ) ;
557
+ }
558
+ } ) ;
549
559
550
- Trace ( $ "< ManagedHost.LoadAssembly() => { assemblyFilePath } (native library)") ;
551
- return null ! ;
552
- }
553
- catch ( FileNotFoundException fnfex )
560
+ if ( assembly != null )
554
561
{
555
- throw new FileNotFoundException (
556
- $ "Assembly file not found: { assemblyNameOrFilePath } ", fnfex ) ;
562
+ _loadedAssembliesByName . GetOrAdd ( assembly . GetName ( ) . Name ! , assembly ) ;
557
563
}
558
564
559
- _loadedAssembliesByPath . Add ( assemblyFilePath , assembly ) ;
560
- _loadedAssembliesByName . Add ( assembly . GetName ( ) . Name ! , assembly ) ;
561
-
562
- Trace ( $ "< ManagedHost.LoadAssembly() => { assemblyFilePath } , { assembly . GetName ( ) . Version } ") ;
565
+ string version = assembly ? . GetName ( ) . Version ? . ToString ( ) ?? "(native library)" ;
566
+ Trace ( $ "< ManagedHost.LoadAssembly() => { assemblyFilePath } { version } ") ;
563
567
return assembly ;
564
568
}
565
569
0 commit comments