add class to load assembly and resolve dependencies for each plugin

This commit is contained in:
Jeremy Wu 2020-09-16 21:12:43 +10:00
parent 97f7b48aa1
commit 1e5d7bd928
2 changed files with 51 additions and 6 deletions

View file

@ -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));
}
}
}

View file

@ -41,9 +41,9 @@ namespace Flow.Launcher.Core.Plugin
{
#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 @@ namespace Flow.Launcher.Core.Plugin
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);
}