Reputation: 341
I have an executable that depends on a library. I also have a "loader" application, which loads the executable into a seperate AppDomain (my "sandbox") and runs it there. The library needs initialization from outside the sandbox, so I need to load the library before I load the executable. This works as expected, but when I now load the executable, the library is loaded another time, and the executable uses the uninitialized copy.
This only occurs if I load the library like this:
Assembly.Load(File.ReadAllBytes(assemblyFile.FullName));
instead of this:
Assembly.LoadFrom(assemblyFile.FullName);
However, using LoadFrom locks the file. I need to be able to delete/write the file, because my application needs to be able to reload the entire sandbox and all assemblies in it.
I also tried registering AppDomain.AssemblyResolve, but it is only called if it does not find the file, which isn't exactly what I want ...
Example log output:
So my question is: How do I force .net to use the already loaded assembly instead of loading a duplicate?
Upvotes: 4
Views: 1132
Reputation: 341
I ended up modifying my AppDomainSetup of the sandbox:
domainSetup.DisallowApplicationBaseProbing = true;
Now, AssemblyResolve will be called everytime (no autodiscover for assemblies). Now I can just load assemblies from a byte[] and cache them (thanks to @DanField who suggested caching assemblies)
Upvotes: 3
Reputation: 21641
From the remarks on Assembly.Load(Byte[])
:
Note that this method overload always creates a new Assembly object with its own mapping.
You can't use that overload if you want to reuse your loaded assemblies (without extra work anyway - the Framework won't automatically do it for you here).
You might be able to use the Assembly.Load(string)
or just Type.GetType(string)
methods here, but I suspect that's still going to end up locking files you want to modify. I'm not really sure how to make sense of modifying those files at run time to be honest though - what's the expected behavior if you delete or change a loaded assembly? Reload it? Have the modified code entered into memory?
You might need to create some kind of assembly caching mechanism of your own. If the assemblies aren't that large and you can afford to keep them in memory, it might be something as simple as a Dictionary<string, Assembly>
- and just check if the dictionary has your assembly before loading it, otherwise load it using Assembly.Load(Byte[])
the way you are now.
Upvotes: 3