From 1e5d7bd928f6e77abbee00f5f9cc0f09fc0309a8 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Wed, 16 Sep 2020 21:12:43 +1000 Subject: [PATCH] add class to load assembly and resolve dependencies for each plugin --- .../Plugin/PluginAssemblyLoader.cs | 45 +++++++++++++++++++ Flow.Launcher.Core/Plugin/PluginsLoader.cs | 12 ++--- 2 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 Flow.Launcher.Core/Plugin/PluginAssemblyLoader.cs diff --git a/Flow.Launcher.Core/Plugin/PluginAssemblyLoader.cs b/Flow.Launcher.Core/Plugin/PluginAssemblyLoader.cs new file mode 100644 index 00000000000..5bbcd115803 --- /dev/null +++ b/Flow.Launcher.Core/Plugin/PluginAssemblyLoader.cs @@ -0,0 +1,45 @@ +using System; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Loader; + +namespace Flow.Launcher.Core.Plugin +{ + internal class PluginAssemblyLoader : AssemblyLoadContext + { + private readonly AssemblyDependencyResolver dependencyResolver; + + private readonly AssemblyName assemblyName; + + internal PluginAssemblyLoader(string assemblyFilePath) + { + dependencyResolver = new AssemblyDependencyResolver(assemblyFilePath); + assemblyName = new AssemblyName(Path.GetFileNameWithoutExtension(assemblyFilePath)); + } + + internal Assembly LoadAssemblyAndDependencies() + { + return LoadFromAssemblyName(assemblyName); + } + + protected override Assembly Load(AssemblyName assemblyName) + { + string assemblyPath = dependencyResolver.ResolveAssemblyToPath(assemblyName); + + if (assemblyPath != null) + { + return LoadFromAssemblyPath(assemblyPath); + } + + return null; + } + + internal Type FromAssemblyGetTypeOfInterface(Assembly assembly, Type type) + { + var allTypes = assembly.ExportedTypes; + + return allTypes.First(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(type)); + } + } +} diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs index 1025f9bae34..224dbd85e92 100644 --- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs +++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs @@ -41,9 +41,9 @@ public static IEnumerable DotNetPlugins(List source) { #if DEBUG - var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(metadata.ExecuteFilePath); - var types = assembly.GetTypes(); - var type = types.First(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IPlugin))); + var assemblyLoader = new PluginAssemblyLoader(metadata.ExecuteFilePath); + var assembly = assemblyLoader.LoadAssemblyAndDependencies(); + var type = assemblyLoader.FromAssemblyGetTypeOfInterface(assembly, typeof(IPlugin)); var plugin = (IPlugin)Activator.CreateInstance(type); #else Assembly assembly = null; @@ -51,10 +51,10 @@ public static IEnumerable DotNetPlugins(List source) try { - assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(metadata.ExecuteFilePath); + var assemblyLoader = new PluginAssemblyLoader(metadata.ExecuteFilePath); + assembly = assemblyLoader.LoadAssemblyAndDependencies(); - var types = assembly.GetTypes(); - var type = types.First(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IPlugin))); + var type = assemblyLoader.FromAssemblyGetTypeOfInterface(assembly, typeof(IPlugin)); plugin = (IPlugin)Activator.CreateInstance(type); }