From 96f5b61b15fa94a6d0298c608831dd84dd5e5cb4 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sat, 29 Feb 2020 01:23:08 +0100 Subject: [PATCH] Implementing plugin's external dependencies loading --- Kyoo.Common/Kyoo.Common.csproj | 2 +- Kyoo/Controllers/PluginManager.cs | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Kyoo.Common/Kyoo.Common.csproj b/Kyoo.Common/Kyoo.Common.csproj index 59e671a5..407d7512 100644 --- a/Kyoo.Common/Kyoo.Common.csproj +++ b/Kyoo.Common/Kyoo.Common.csproj @@ -11,7 +11,7 @@ SDG GPL-3.0-or-later true - 1.0.9 + 1.0.10 diff --git a/Kyoo/Controllers/PluginManager.cs b/Kyoo/Controllers/PluginManager.cs index 66f47c94..079b5314 100644 --- a/Kyoo/Controllers/PluginManager.cs +++ b/Kyoo/Controllers/PluginManager.cs @@ -3,12 +3,39 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.Loader; using Kyoo.Models; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace Kyoo.Controllers { + public class PluginDependencyLoader : AssemblyLoadContext + { + private readonly AssemblyDependencyResolver _resolver; + + public PluginDependencyLoader(string pluginPath) + { + _resolver = new AssemblyDependencyResolver(pluginPath); + } + + protected override Assembly Load(AssemblyName assemblyName) + { + string assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName); + if (assemblyPath != null) + return LoadFromAssemblyPath(assemblyPath); + return base.Load(assemblyName); + } + + protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) + { + string libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName); + if (libraryPath != null) + return LoadUnmanagedDllFromPath(libraryPath); + return base.LoadUnmanagedDll(unmanagedDllName); + } + } + public class PluginManager : IPluginManager { private readonly IServiceProvider _provider; @@ -47,7 +74,8 @@ namespace Kyoo.Controllers { try { - Assembly ass = Assembly.LoadFile(Path.GetFullPath(path)); + PluginDependencyLoader loader = new PluginDependencyLoader(Path.GetFullPath(path)); + Assembly ass = loader.LoadFromAssemblyPath(Path.GetFullPath(path)); return (from type in ass.GetTypes() where typeof(IPlugin).IsAssignableFrom(type) select (IPlugin) ActivatorUtilities.CreateInstance(_provider, type)).FirstOrDefault();