diff --git a/src/app/dev/DevToys.Core/Mef/AssemblyIsolation.cs b/src/app/dev/DevToys.Core/Mef/AssemblyIsolation.cs new file mode 100644 index 0000000000..d60460223e --- /dev/null +++ b/src/app/dev/DevToys.Core/Mef/AssemblyIsolation.cs @@ -0,0 +1,26 @@ +using System.Reflection; +using System.Runtime.Loader; + +namespace DevToys.Core.Mef; + +// See https://learn.microsoft.com/en-us/dotnet/core/dependency-loading/understanding-assemblyloadcontext +internal sealed class AssemblyIsolation : AssemblyLoadContext +{ + private readonly AssemblyDependencyResolver _resolver; + + internal AssemblyIsolation(string entryPointAssemblyPath) + { + _resolver = new AssemblyDependencyResolver(entryPointAssemblyPath); + } + + protected override Assembly? Load(AssemblyName assemblyName) + { + string? assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName); + if (assemblyPath != null) + { + return LoadFromAssemblyPath(assemblyPath); + } + + return null; + } +} diff --git a/src/app/dev/DevToys.Core/Mef/RecursiveDirectoryCatalog.cs b/src/app/dev/DevToys.Core/Mef/RecursiveDirectoryCatalog.cs index 2fe1eb7c38..222698670a 100644 --- a/src/app/dev/DevToys.Core/Mef/RecursiveDirectoryCatalog.cs +++ b/src/app/dev/DevToys.Core/Mef/RecursiveDirectoryCatalog.cs @@ -14,6 +14,7 @@ internal sealed partial class RecursiveDirectoryCatalog : ComposablePartCatalog, { private readonly ILogger _logger; private readonly string _path; + private AssemblyIsolation? _assemblyIsolation; private AggregateCatalog? _aggregateCatalog; /// @@ -122,7 +123,13 @@ private bool AddLibraryToMefCatalog(string filePath) try { AssemblyCount++; - var asmCat = new AssemblyCatalog(filePath); + + // Create an isolation context for the plugin. + // This allows to load dependencies version that the plugin asks, even if DevToys uses a different version of that same dependency. + _assemblyIsolation ??= new AssemblyIsolation(filePath); + + Assembly assembly = _assemblyIsolation.LoadFromAssemblyPath(filePath); + var asmCat = new AssemblyCatalog(assembly); // Force MEF to load the plugin and figure out if there are any exports // good assemblies will not throw the RTLE exception and can be added to the catalog