private async Task <Assembly?> LoadAssemblyByNameAsync( AssemblyName assemblyName, AssemblyLoaderContext?context) { if (_assemblyLoadContext == null) { return(null); } IAssemblyComparer comparer = GetAssemblyNameComparer(assemblyName); if (TryGetAlreadyLoadedAssembly(assemblyName, comparer, out var alreadyLoadedAssembly)) { return(alreadyLoadedAssembly); } if (TryGetAlreadyLoadingAssembly(assemblyName, comparer, out var assemblyLoadingTask)) { Debug.WriteLine($"Waiting for Loading Assembly '{assemblyName}'"); return(await assemblyLoadingTask !.ConfigureAwait(false)); } AssemblyLoaderContext contextScope = context == null ? new AssemblyLoaderContext(assemblyName) : context.NewScope(assemblyName); Assembly?assembly = await PerformAssemblyLoad(assemblyName, comparer, contextScope).ConfigureAwait(false); return(assembly); }
private async Task <Assembly?> ResolveAssembly( AssemblyName assemblyName, IAssemblyComparer comparer, AssemblyLoaderContext context) { if (_assemblyLoadContext == null) { return(null); } // Try loading the assembly by name (this works when the assembly is part of the bootloader, but never used explicitly) Assembly?assembly = _assemblyLoadContext.Load(assemblyName); if (assembly != null) { return(assembly); } AssemblyData?data = await _assemblyDataProvider.GetAssemblyDataAsync(assemblyName, context).ConfigureAwait(false); if (data == null) { Debug.WriteLine($"Failed to resolve Assembly: '{assemblyName}'"); return(null); } var dependencies = await ResolveDependencies(assemblyName, data, context).ConfigureAwait(false); if (dependencies == null) { return(null); } return(_assemblyLoadContext.Load(data)); }
public Assembly?GetLoadedAssemblyByName(AssemblyName assemblyName) { IAssemblyComparer comparer = GetAssemblyNameComparer(assemblyName); if (TryGetAlreadyLoadedAssembly(assemblyName, comparer, out var alreadyLoadedAssembly)) { return(alreadyLoadedAssembly); } return(null); }
private bool TryGetAlreadyLoadingAssembly( AssemblyName assemblyName, IAssemblyComparer comparer, out Task <Assembly?>?assemblyLoadingTask) { var assemblyLoadingEntry = _loadingAssemblies .FirstOrDefault(kv => comparer.Equals(assemblyName, kv.Key)); if (assemblyLoadingEntry.Key == null) { assemblyLoadingTask = null; return(false); } assemblyLoadingTask = assemblyLoadingEntry.Value; return(true); }
private bool TryGetAlreadyLoadedAssembly( AssemblyName assemblyName, IAssemblyComparer comparer, out Assembly?assembly) { if (_assemblyLoadContext == null) { assembly = null; return(false); } Assembly?loadedAssembly = _assemblyLoadContext.AllAssemblies .FirstOrDefault(a => comparer.Equals(assemblyName, a.GetName())); assembly = loadedAssembly; return(loadedAssembly != null); }
private async Task <Assembly?> PerformAssemblyLoad( AssemblyName assemblyName, IAssemblyComparer comparer, AssemblyLoaderContext context) { var assemblyLoadingTaskSource = new TaskCompletionSource <Assembly?>(); if (!TryActionRepeteadly(() => _loadingAssemblies.TryAdd(assemblyName, assemblyLoadingTaskSource.Task), 5)) { throw new InvalidOperationException($"Unable to Load Assembly '{assemblyName}': Concurrency error (adding)"); } Debug.WriteLine($"Loading Assembly: '{assemblyName}'"); Assembly?assembly = await ResolveAssembly(assemblyName, comparer, context).ConfigureAwait(false); if (assembly != null) { Debug.WriteLine($"Loaded Assembly: '{assemblyName}'"); foreach (var assemblyLoadCallback in _onAssemblyLoad) { await assemblyLoadCallback.Invoke(assembly).ConfigureAwait(false); } } else { Debug.WriteLine($"Assembly '{assemblyName}' failed to load"); } assemblyLoadingTaskSource.SetResult(assembly); if (!TryActionRepeteadly(() => _loadingAssemblies.TryRemove(assemblyName, out var _), 5)) { throw new InvalidOperationException($"Unable to Load Assembly '{assemblyName}': Concurrency error (removing)"); } return(assembly); }