Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AppDomain dependency resolving order

I have a .Net multi-appdomain application that resembles a scheduler. Default app domain has a timer and a list of jobs that are contained each in it's own assembly and ran on separate appdomains. Assemblies containing jobs are kept each in it's separate directory under the application root.

(root)\Library\AssemblyName\

Each assembly directory contains the assembly and its dependencies. Some of those dependencies(e.g. log4net) are contained in the root directory as well because the default domain has it's separate log. I want to load the job assembly and its dependencies from the assembly directory if they exist there, and if not i want to load them from the application root directory. Both main appdomain and child domains use the same library with Interfaces similar to Quartz's IJob interface, so this assembly needs to be loaded from the same file.

The reason for this rather odd requirement is that application jobs should have automatic update ability. So a specially designed class would download the job from an API, unload the appdomain the job is on, delete the job assembly with all the dependencies and reload the appdomain and restart the job, without interfering with the other jobs operation. I've tried using AppdomainSetup to set the Assembly directory before the root directory,

domainSetup.PrivateBinPath = @"\\Library\\AssemblyName\\" 

however my dependencies get resolved from the root directory every time.

So basically i want my dependency to be resolved from the 1. Assembly folder if possible 2. Root directory

like image 661
Ivan Kvolik Avatar asked Sep 26 '22 02:09

Ivan Kvolik


1 Answers

Root always takes precedence. There's a few ways around this:

Just make sure the root doesn't actually have any of the references - make your main domain's base directory into another subdirectory rather than the root.

Or, make good use of the ApplicationBase in domain setup (that is, change the root, rather than the private bin path)

Or, use PrivateBinPathProbe to prevent any assembly loading from the root.

Or, set DisallowApplicationBaseProbing and implement the AppDomain.AssemblyResolve event - this gives you manual control over all assembly resolution in the domain. This is probably the one you really want, though I'd combine it with making the base domain just another "module" as well.

like image 65
Luaan Avatar answered Oct 03 '22 15:10

Luaan