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