-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Description
Greetings! Using Core 3.0 with collectible AssemblyLoadContext, in order to unload/reload dynamically loaded assemblies on demand.
I'm not sure if it's bug or a misunderstanding of AssemblyResolve event handler, let me try to explain:
I have configured cache of dynamically loading/reloading/unloading assemblies, separate collectible AssemblyLoadContext per loaded assembly. Everything works perfect, but i have encountered issues with 3-rd party library.
This 3-rd party library have serialization logic in some parts of code flow, using kind of BinarySerializer extension which is trying to access types from any of mine dynamically loaded assembly by standard Type.GetType(string typeName) method. Such behavior throwing errors because types of dynamically loaded assembly are not in AppDomain.CurrentDomain but in separate collectible AssemblyLoadContext.
To save supporting of this 3-rd party library, i have added AssemblyResolve event handler, to guide system where it should looking for assembly:
AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolveEventHandler;
Where handler looks like:
private static Assembly AssemblyResolveEventHandler(object sender, ResolveEventArgs resolveEvent)
{
var dynamicPartsManager = StaticServiceProvider.Stash.GetService<IDynamicPartsManager>();
if (dynamicPartsManager.DynamicAssemblyLoaded)
{
var assemblyFriendlyName = resolveEvent.Name.Substring(
0,
resolveEvent.Name.IndexOf(",", StringComparison.InvariantCultureIgnoreCase)
);
if (DynamicAssemblyLoader.HasLoadedDomain(assemblyFriendlyName, out AssemblyLoadContext domain))
{
var dynamicAssembly = domain.Assemblies.FirstOrDefault(assembly => assembly.FullName == resolveEvent.Name);
return dynamicAssembly;
}
}
return null;
}
Where DynamicAssemblyLoader is my cache of dynamically loaded assemblies per AssemblyLoadContext.
When looking assembly was successfully found and returned it throws exception:
System.IO.FileLoadException: Could not load file or assembly 'MyDynamicAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. Operation is not supported. (0x80131515)
File name: 'MyDynamicAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
---> System.NotSupportedException: Resolving to a collectible assembly is not supported.
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, StackCrawlMarkHandle stackMark, ObjectHandleOnStack assemblyLoadContext, Boolean loadTypeFromPartialName, ObjectHandleOnStack type, ObjectHandleOnStack keepalive)
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, StackCrawlMark& stackMark, AssemblyLoadContext assemblyLoadContext, Boolean loadTypeFromPartialName)
at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, StackCrawlMark& stackMark)
at System.Type.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase)
...
3-rd party library call stack
Probably it is not possible to "just return" found Assembly or am i doing something wrong?
If anybody have any suggestions - please, share them, cause i'm out of ideas :(