From aad884b5bc4be39f82ba39c5f0b97cda88b6ce93 Mon Sep 17 00:00:00 2001 From: Artem Saikin Date: Tue, 12 Oct 2021 12:11:15 +0300 Subject: [PATCH 1/2] Improve plugin finder to ignore already loaded assemblies from runtime --- .../Services/PluginFinderBase.cs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/Orc.Extensibility/Services/PluginFinderBase.cs b/src/Orc.Extensibility/Services/PluginFinderBase.cs index 0aa21c88..a1eaa9e2 100644 --- a/src/Orc.Extensibility/Services/PluginFinderBase.cs +++ b/src/Orc.Extensibility/Services/PluginFinderBase.cs @@ -343,6 +343,7 @@ protected virtual async Task FindPluginsInAssemblyAsync(PluginProbingContext con return; } + // Register assembly in their own plugin load context await _runtimeAssemblyResolverService.RegisterAssemblyAsync(assemblyPath); // Important: all types already in the app domain should be included as well @@ -430,6 +431,8 @@ protected virtual async Task FindPluginsInAssemblyAsync(PluginProbingContext con protected virtual List FindResolvableAssemblyPaths(string assemblyPath) { + var assemblyVersions = new Dictionary(StringComparer.OrdinalIgnoreCase); + if (_appDomainResolvablePaths.Count == 0) { foreach (var loadedAssembly in AppDomain.CurrentDomain.GetLoadedAssemblies()) @@ -452,6 +455,11 @@ protected virtual List FindResolvableAssemblyPaths(string assemblyPath) } _appDomainResolvablePaths.Add(location); + + var fileName = Path.GetFileNameWithoutExtension(location); + var version = GetFileVersion(location); + + assemblyVersions[fileName] = version; } } @@ -465,6 +473,25 @@ where x.PluginLocation.EqualsIgnoreCase(assemblyPath) { foreach (var runtimeAssembly in pluginLoadContext.RuntimeAssemblies) { + if (!_fileService.Exists(runtimeAssembly.Location)) + { + continue; + } + + var fileName = Path.GetFileNameWithoutExtension(runtimeAssembly.Location); + var version = GetFileVersion(runtimeAssembly.Location); + + if (assemblyVersions.TryGetValue(fileName, out var existingVersion)) + { + if (existingVersion != version) + { + Log.Warning($"Already loaded '{fileName}' version '{existingVersion}', but also found runtime assembly '{version}'. The already loaded assembly will be used to investigate '{assemblyPath}'"); + continue; + } + } + + assemblyVersions[fileName] = version; + paths.Add(runtimeAssembly.Location); } } @@ -472,6 +499,11 @@ where x.PluginLocation.EqualsIgnoreCase(assemblyPath) return paths; } + protected virtual Version GetFileVersion(string fileName) + { + return AssemblyName.GetAssemblyName(fileName)?.Version ?? new Version("0.0.0"); + } + protected virtual bool ShouldIgnoreAssembly(string assemblyPath) { var fileName = Path.GetFileName(assemblyPath).ToLower(); From b2cab9119a7fa7fe1ada949565429023ab9183e6 Mon Sep 17 00:00:00 2001 From: Artem Saikin Date: Tue, 12 Oct 2021 12:12:15 +0300 Subject: [PATCH 2/2] Approve changes --- src/Orc.Extensibility.Tests/Orc.Extensibility.approved.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Orc.Extensibility.Tests/Orc.Extensibility.approved.cs b/src/Orc.Extensibility.Tests/Orc.Extensibility.approved.cs index d37a62c0..76fcc7db 100644 --- a/src/Orc.Extensibility.Tests/Orc.Extensibility.approved.cs +++ b/src/Orc.Extensibility.Tests/Orc.Extensibility.approved.cs @@ -173,6 +173,7 @@ protected virtual System.Threading.Tasks.Task FindPluginsInDirectoryAsync(Orc.Ex protected virtual System.Threading.Tasks.Task FindPluginsInLoadedAssembliesAsync(Orc.Extensibility.PluginProbingContext context) { } protected virtual System.Threading.Tasks.Task FindPluginsInUnloadedAssembliesAsync(Orc.Extensibility.PluginProbingContext context) { } protected virtual System.Collections.Generic.List FindResolvableAssemblyPaths(string assemblyPath) { } + protected virtual System.Version GetFileVersion(string fileName) { } protected virtual System.Collections.Generic.List GetOldestDuplicates(System.Collections.Generic.List duplicates) { } protected abstract bool IsPlugin(Orc.Extensibility.PluginProbingContext context, System.Type type); protected virtual bool IsPluginFastPreCheck(Orc.Extensibility.PluginProbingContext context, System.Type type) { }