-
Notifications
You must be signed in to change notification settings - Fork 4.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question about Assembly loading & Resolving #62391
Comments
Tagging subscribers to this area: @vitek-karas, @agocke, @VSadov Issue DetailsHello, I've a question about best practice to do some Assembly Loading. I've a complex software wich uses many different Assemblies. I want be able to replace some of the DLLs at runtime, but I don't want to use a own Assembly load Context. I thought I could hijack Assembly loading via AppDomain.Resolve, but it is only called when the Assemblies are not directly found.
|
Hello, I persume you avoid using Unfortunately there is no such solution that works in both frameworks. If you want to control first-chance assembly loading on modern .NET, you have to create an
I use this on my code and it works: using var file = File.OpenRead("MyAssembly.dll");
alc.LoadFromStream(file);
|
@teo-tsirpanis no, our software is completely migrated to netcore. I now solved it, via moving the whole application and all assemblies in a subdirectly and create a loader program. So all assemblies are not found and so the AssemblyLoadContext.Resolve is called. |
But I thought maybe this would be easier, so I don't need an extra loader, I only wanted to change how the default AssemblyLoadContext loads the Assemblies from FileSystem (it should use a ByteArray), so it does not lock the files. |
@jogibear9988 There are a lot of options in the assembly load arena. I'd recommend reading the following: https://docs.microsoft.com/dotnet/core/dependency-loading/overview. It discusses all the potential points of access and even the algorithm. |
@AaronRobinsonMSFT |
Sorry.... Found it. Assembly.Load has 2 Byte Arrays as parameter... |
I've created this class, maybe it is usefull for someone...
|
Couple of notes on this:
|
But maybe you have seen, I load the Framework assemblies direct from the disk:
so the issue should not be present? |
Sorry - I missed that part - yes, in that case the performance should not take a big hit. |
I know find, that my loading approach is barely to simple. see issue: dotnet/SqlClient#1424 there is also a runtimes folder, and some dll's needed to be loaded from this directory (the ones in the app dir are only stubs?). I thought maybe AssemblyDependencyResolver would help, but I did not think so. I also found this: #1050 (comment) does it mean the complete resolving strategy is only in unmanged code? |
Let's take a step back, why do you need to load all assemblies from memory? |
I don't need to load all from memory, but I need to load some of the assemblies from memory. But I thought it would be a good idea, to move the whole program into a subdirectory so I can implement my own assembly loader. But now I see that the whole assembly loading Process in netcore is much complexer. Don't know what the best solution now is. The best would be if the native assembly loader would have a callback wich the DLL it found, and I could load the Assembly how I like. |
Which are these "some" assemblies and why do you want to load them from memory? |
This are some assemblies from our application. I want to load the from memory so I could replace them later in the file system and load new Versions of them. I don't want to create an assembly load context, I only want to load the new ones into memory, and then use them. This all works, with my loader, but now SqlServer access didn't work any more (I tested with sqlite), cause I loaded the sqlserver dll from the application dir and not the on from the "runtimes" directory. |
This assemblyloader now works...
|
To load these new versions you have to restart the process. Dynamically loading and unloading assemblies can be done only via an If you want to implement something like an auto-update, I would suggest to place each version to a separate folder, close the old version and start the new, without replacing files. Why are you avoiding using ALCs anyway? You said earlier that your codebase is fully migrated to modern .NET, and from personal experience I can tell you that working with them is a delight. |
no, I can load multiple versions of an assembly. I don't need to unload. This will be cleaned when the software is restared at some time. The little bit more memory usage does not matter for us at the moment. The Loading already works, the only thing wich does not work, is sql server cause it's implentation dll is in the runtimes dir, and now cause it could not load it's unmanged code.
it has nothing to do with auto update.
I don't need them. |
As shown in https://docs.microsoft.com/en-us/dotnet/core/dependency-loading/loading-managed, If you really don't want to use your own ALCs (and I will stress again that your existing approach IMHO looks inefficient and unnecessarily complicated), you can try this, after loading an assembly from memory: AssemblyLoadContext.GetLoadContext(assembly).ResolvingUnmanagedDll += Default_ResolvingUnmanagedDll; You can load native libraries using methods in the |
should the AssemblyLoadContext.Default.ResolvingUnmanagedDll be called for a DLLImport in Microsoft.Data.SqlClient? |
Now it works.
was the key. But I think I will switch to, that I only move the DLLs wich are needed to be replaced, into a subdirectory. So the whole AssemblyLoader will get simpler again.
|
Tell me about your app if you want, what underlying reason motivated you to implement this custom assembly loader? |
We have a complex APP, with over 100 Projects in the solution. But after switching to NetCore, we decided to Drop the communication Overhead, and switched to direct interface calls. So at first I tried to load my Services (the ones wich were in different appdomains before), into AssemblyLoadContexts, but th eProblem is, they refrence each other, and when then an Assembly is loaded to another LoadContext, they types are not the same (same as I load a assembly multiple times to one load context). But now I thought an easier solution would be only to reload the new Assembly (and leave the old one in memory). Initially I thouhght AssemblyResolve would be called for all Assemblies, then I saw it's only called for the ones wich are not found... And so I started workin on this. One more Information, we only need the reload during the development of our customer solution, later when the software runs for weeks, or months we will not use this. |
Hello,
I've a question about best practice to do some Assembly Loading.
I've a complex software wich uses many different Assemblies. I want be able to replace some of the DLLs at runtime, but I don't want to use a own Assembly load Context. I thought I could hijack Assembly loading via AppDomain.Resolve, but it is only called when the Assemblies are not directly found.
Is there a Callback wich is use before a Assemblie is loaded, even when it is found in the File System? Cause I want to load them in a way so the File is not locked.
The text was updated successfully, but these errors were encountered: