The .NET Core 3.0 has a new feature to enable unloading assemblies from memory, called unloadable AssemblyLoadContext. This feature is useful e.g. for implementing unloadable plugins.
In WPF, the MS.Internal.Resources.ResourceManagerWrapper holds on the assemblies containing controls forever (the assemblies are added to an internal container in the AppDomain.CurrentDomain.AssemblyLoad event handler and never removed).
So when the assembly is loaded into an unloadable AssemblyLoadContext, the resource container prevents the assembly from ever being unloaded, as the AssemblyLoadContext unloadability relies on GC and all references to the assembly need to go away before it can be unloaded.
To make WPF unloadability friendly, adding an ability to remove an assembly from the resource container would be needed.
It seems the following changes should be sufficient:
In the existing AppDomain.CurrentDomain.AssemblyLoad event handler in the ResourceContainer , the resource manager hooks the AssemblyLoadContext.Unloading event for all assemblies that have IsCollectible property true. The AssemblyLoadEvent.GetLoadContext(Assembly) would be used to get the context to hook the event handler on from the assembly.
When the Unloading event fires, the resource container removes the assembly from its cache
The .NET Core 3.0 has a new feature to enable unloading assemblies from memory, called unloadable AssemblyLoadContext. This feature is useful e.g. for implementing unloadable plugins.
In WPF, the
MS.Internal.Resources.ResourceManagerWrapper
holds on the assemblies containing controls forever (the assemblies are added to an internal container in theAppDomain.CurrentDomain.AssemblyLoad
event handler and never removed). So when the assembly is loaded into an unloadableAssemblyLoadContext
, the resource container prevents the assembly from ever being unloaded, as theAssemblyLoadContext
unloadability relies on GC and all references to the assembly need to go away before it can be unloaded.To make WPF unloadability friendly, adding an ability to remove an assembly from the resource container would be needed.
It seems the following changes should be sufficient:
AppDomain.CurrentDomain.AssemblyLoad
event handler in theResourceContainer
, the resource manager hooks theAssemblyLoadContext.Unloading
event for all assemblies that haveIsCollectible
property true. TheAssemblyLoadEvent.GetLoadContext(Assembly)
would be used to get the context to hook the event handler on from the assembly.Unloading
event fires, the resource container removes the assembly from its cache