private static AssemblyLoadContext CreateLoadContext(string assemblyPath, Core.ILogger logger = null) { var validatedPath = ValidateFilePath(assemblyPath, logger); if (validatedPath == null) { return(null); } var mainAssemblyName = Path.GetFileNameWithoutExtension(validatedPath); var builder = new AssemblyLoadContextBuilder(); // Set base directory. var baseDir = Path.GetDirectoryName(validatedPath); builder.SetBaseDirectory(baseDir); logger?.LogTrace($"Base directory: '{baseDir}'"); // Add deps file as a source for finding dependencies. var depsJsonFile = Path.Combine(baseDir, $"{mainAssemblyName}.deps.json"); if (File.Exists(depsJsonFile)) { builder.AddDependencyContext(depsJsonFile); logger?.LogTrace($"Added '{depsJsonFile}' as a deps file dependency"); } // Add runtimeconfig file as a source for finding dependencies. var pluginRuntimeConfigFile = Path.Combine(baseDir, $"{mainAssemblyName}.runtimeconfig.json"); builder.TryAddAdditionalProbingPathFromRuntimeConfig(pluginRuntimeConfigFile, includeDevConfig: true, out _); return(builder.Build()); }
private static IReadOnlyList <Assembly> LoadAssemblyFromName( AssemblyLoadContext loadContext, AssemblyName assemblyName, IEnumerable <string> dependencyDirectories, Core.ILogger logger = null) { // If assembly exists in any of the dependency paths then load it from there. var dependencyPath = dependencyDirectories. Select(d => { try { return (Directory.EnumerateFiles(d, $"{assemblyName.Name}.dll", SearchOption.AllDirectories). FirstOrDefault()); } catch (Exception) { return(null); } }). Where(p => p != null). FirstOrDefault(); if (!string.IsNullOrEmpty(dependencyPath)) { return(LoadAssemblyFromPath(loadContext, dependencyPath, dependencyDirectories, logger)); } // Otherwise load by name from the context. var output = new List <Assembly>(); try { output.Add(loadContext.LoadFromAssemblyName(assemblyName)); logger?.LogTrace($"Loaded assembly: '{output[0].FullName}'"); } catch (Exception e) { if (logger != null) { logger?.LogWarning($"Failed to load assembly: {e.Message.ToDistinctLines()}"); } return(Array.Empty <Assembly>()); } // Load referenced assemblies. foreach (var referencedAssemblyName in output[0].GetReferencedAssemblies()) { if (!IsAssemblyLoaded(referencedAssemblyName)) { output.AddRange( LoadAssemblyFromName(loadContext, referencedAssemblyName, dependencyDirectories, logger)); } } return(output); }
private static IReadOnlyList <Assembly> LoadAssemblyFromPath( AssemblyLoadContext loadContext, string path, IEnumerable <string> dependencyDirectories, Core.ILogger logger = null) { // Validate path. var validatedPath = ValidateFilePath(path, logger); if (validatedPath == null) { return(Array.Empty <Assembly>()); } // Load assembly. var output = new List <Assembly>(); try { output.Add(loadContext.LoadFromAssemblyPath(validatedPath)); logger?.LogTrace($"Loaded assembly: '{output[0].FullName}'"); } catch (Exception e) { if (logger != null) { logger?.LogWarning($"Failed to load assembly: {e.Message.ToDistinctLines()}"); } return(Array.Empty <Assembly>()); } // Load referenced assemblies. foreach (var referencedAssemblyName in output[0].GetReferencedAssemblies()) { if (!IsAssemblyLoaded(referencedAssemblyName)) { output.AddRange( LoadAssemblyFromName(loadContext, referencedAssemblyName, dependencyDirectories, logger)); } } return(output); }