public void LoadStreamsIntoContext(CollectibleAssemblyLoadContext context, string moduleFolder, Assembly assembly) { AssemblyName[] references = assembly.GetReferencedAssemblies(); foreach (AssemblyName item in references) { string name = item.Name; string version = item.Version.ToString(); Stream stream = _referenceContainer.GetStream(name, version); if (stream != null) { _logger.LogDebug($"Found the cached reference '{name}' v.{version}"); assembly = context.Assemblies.FirstOrDefault(a => a.GetName().Name == name); if (assembly == null) { assembly = context.LoadFromStream(stream); } } else { if (IsSharedFreamwork(name) || IsLoadedByDefault(item.FullName)) { continue; } string dllName = $"{name}.dll"; string filePath = $"{moduleFolder}/{dllName}"; if (!File.Exists(filePath)) { _logger.LogWarning($"The package '{dllName}' in '{filePath}' is missing."); continue; } using (FileStream fs = new FileStream(filePath, FileMode.Open)) { assembly = context.LoadFromStream(fs); MemoryStream memoryStream = new MemoryStream(); fs.Position = 0; fs.CopyTo(memoryStream); fs.Position = 0; memoryStream.Position = 0; _referenceContainer.SaveStream(name, version, memoryStream); } } LoadStreamsIntoContext(context, moduleFolder, assembly); } }
public void LoadModule(string moduleName, bool isInstall = true) { if (!_pluginsLoadContexts.Any(moduleName)) { CollectibleAssemblyLoadContext context = new CollectibleAssemblyLoadContext(moduleName); string filePath = Path.Combine(_baseDirectory, _pluginOptions.InstallBasePath, moduleName, $"{moduleName}.dll"); string referenceFolderPath = Path.Combine(_baseDirectory, _pluginOptions.InstallBasePath, moduleName); using (FileStream fs = new FileStream(filePath, FileMode.Open)) { Assembly assembly = context.LoadFromStream(fs); _referenceLoader.LoadStreamsIntoContext(context, referenceFolderPath, assembly); context.SetEntryPoint(assembly); context.PluginAssemblyParts.Add(new PluginAssemblyPart(assembly)); if (!AdditionalReferencePathHolder.AdditionalReferencePaths.Contains(filePath)) { AdditionalReferencePathHolder.AdditionalReferencePaths.Add(filePath); } } var viewsFilePath = Path.Combine(_baseDirectory, _pluginOptions.InstallBasePath, moduleName, $"{moduleName}.Views.dll"); if (File.Exists(viewsFilePath)) { using (FileStream fs = new FileStream(viewsFilePath, FileMode.Open)) { Assembly assembly = context.LoadFromStream(fs); context.PluginAssemblyParts.Add(new CompiledRazorAssemblyPart(assembly)); _referenceLoader.LoadStreamsIntoContext(context, referenceFolderPath, assembly); } } var pluginWebRoot = Path.Combine(_baseDirectory, _pluginOptions.InstallBasePath, moduleName, $"wwwroot"); DirectoryCopy(pluginWebRoot, _env.WebRootPath, true); _pluginsLoadContexts.Add(moduleName, context); if (isInstall) { ModuleChangeEventHandler?.Invoke(ModuleEvent.Installed, context); } else { ModuleChangeEventHandler?.Invoke(ModuleEvent.Loaded, context); } } }