From 9fa8ac5762aa3d320f699238abe43a680d08298b Mon Sep 17 00:00:00 2001 From: David Maas Date: Thu, 11 Jul 2024 22:22:02 -0500 Subject: [PATCH] Fix redundant assembly resolves resulting in redundant assembly loads Also added copying the NuGet.config to the repack output directory for ease of testing. Fixes https://github.com/bonsai-rx/bonsai/issues/1901 --- Bonsai/Bonsai.csproj | 1 + Bonsai/SystemResourcesExtensionsSupport.cs | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Bonsai/Bonsai.csproj b/Bonsai/Bonsai.csproj index 33be0269..66926e89 100644 --- a/Bonsai/Bonsai.csproj +++ b/Bonsai/Bonsai.csproj @@ -102,6 +102,7 @@ + diff --git a/Bonsai/SystemResourcesExtensionsSupport.cs b/Bonsai/SystemResourcesExtensionsSupport.cs index a0c46421..bafc660e 100644 --- a/Bonsai/SystemResourcesExtensionsSupport.cs +++ b/Bonsai/SystemResourcesExtensionsSupport.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Diagnostics; using System.Reflection; @@ -16,19 +17,27 @@ internal static class SystemResourcesExtensionsSupport [Conditional("NETFRAMEWORK")] internal static void Initialize() { + // Assembly.Load(byte[]) always results in a new assembly so we need to manually de-duplicate them + ConcurrentDictionary resolveCache = new(); + AppDomain.CurrentDomain.AssemblyResolve += (_, args) => { var assemblyName = new AssemblyName(args.Name); + + if (resolveCache.TryGetValue(assemblyName.Name, out var cachedResult)) + return cachedResult; + using var embeddedAssembly = typeof(SystemResourcesExtensionsSupport).Assembly.GetManifestResourceStream($"{nameof(Bonsai)}.{assemblyName.Name}.dll"); - + if (embeddedAssembly is null) - return null; + return resolveCache.GetOrAdd(assemblyName.Name, (Assembly)null); var assemblyBytes = new byte[embeddedAssembly.Length]; int readLength = embeddedAssembly.Read(assemblyBytes, 0, assemblyBytes.Length); Debug.Assert(readLength == assemblyBytes.Length); var result = Assembly.Load(assemblyBytes); + result = resolveCache.GetOrAdd(assemblyName.Name, result); Debug.WriteLine($"Redirecting '{args.Name}' to embedded '{result.FullName}'"); return result; };