/// <summary> /// Creates a new instance of <see cref="PluginAssemblyResolver" /> which implements the /// <see cref="AppDomain.AssemblyResolve" /> event to load the plugin's and its dependencies' /// assemblies as provided by <paramref name="pluginAndDependenciesAssembliesPath" /> /// </summary> /// <param name="packageRootFolder"> /// The root folder underneath which all packages and their /// assemblies are located /// </param> /// <param name="pluginAndDependenciesAssembliesPath"> /// The file path to plugin's and its /// dependencies' assemblies. Paths should be relative to <paramref name="packageRootFolder" /> /// </param> public static void Initialize(string packageRootFolder, string pluginAndDependenciesAssembliesPath) { if (Instance != null) { throw new InvalidOperationException("An instance of PluginAssemblyResolver already exists."); } var assemblyNamePathMap = new Dictionary <string, string>(); var pluginAndDependenciesAssembliesPathArr = pluginAndDependenciesAssembliesPath.Split( new[] { PluginHostConst.PluginAndDependenciesAssembliesSeparator }, StringSplitOptions.RemoveEmptyEntries); foreach (var assemblyPath in pluginAndDependenciesAssembliesPathArr) { var assemblyName = Path.GetFileNameWithoutExtension(assemblyPath); if (string.IsNullOrWhiteSpace(assemblyName)) { Console.Error.WriteLine( $"PluginAssemblyResolver.Setup: Cannot find assembly file name in assembly path {assemblyPath}. Skipping, this may affect the plugin's ability to run correctly"); continue; } assemblyNamePathMap[assemblyName] = packageRootFolder + assemblyPath; } Instance = new PluginAssemblyResolver(assemblyNamePathMap); }
/// <summary> /// Creates the <see cref="AppDomain" /> that will host the plugin instance. The Assembly /// Resolver for the plugin's and its dependencies' assemblies is instantiated in the plugin's /// AppDomain itself. This avoids any unnecessary cross-AppDomain communication, and doesn't /// require the plugin's AppDomain to load the PluginHost.exe assembly. /// </summary> /// <param name="packageRootFolder"> /// The root folder underneath which all packages and their /// assemblies are located /// </param> /// <param name="pluginAndDependenciesAssembliesPath"> /// The file path to plugin's and its /// dependencies' assemblies. Paths should be relative to <paramref name="packageRootFolder" /> /// </param> /// <returns>The created <see cref="AppDomain" /></returns> private static void CreateAssemblyResolver(string packageRootFolder, string pluginAndDependenciesAssembliesPath) { var pluginManagerInteropAssemblyFilePath = FindAssemblyFilePath( false, null, PluginHostConst.PluginManagerInteropAssemblyName, packageRootFolder, pluginAndDependenciesAssembliesPath); if (string.IsNullOrWhiteSpace(pluginManagerInteropAssemblyFilePath)) { Console.Error.WriteLine( $"Unable to find {PluginHostConst.PluginManagerInteropAssemblyName} assembly file path " + $"in assembly list {pluginAndDependenciesAssembliesPath}"); throw new PluginHostException(PluginHostConst.ExitCouldNotFindInteropAssembly); } PluginAssemblyResolver.Initialize(packageRootFolder, pluginAndDependenciesAssembliesPath); }