Load assemblies with dependencies in a different AppDomain

Konstantinos picture Konstantinos · Aug 16, 2012 · Viewed 8k times · Source

My aim is to make a missing dependency check between 2 given folders. Imagine the following setup.

Root\DirA\A.dll

Root\DirB\B.dll

B depends on A.

So given these folders, I want to create a new AppDomain, load B.dll and have the dependency from DirA(A.dll) automatically resolved and isolated in that new AppDomain.

Isolation is key here given that when I unload this AppDomain I want to create a new one with potentially DirA as a dependency again but DirC libraries that require it so in the case that DirC has a dependency on DirB as well I want it to throw an exception.

Edit: Adding a code example in case that it helps describe my question better.

AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = @"C:\Root";
setup.ApplicationName = "Isolated Domain"
setup.PrivateBinPath = @"DirA;DirB";
setup.PrivateBinPathProbe = "";//disable search in AppBase..
var domain = AppDomain.CreateDomain(Guid.NewGuid().ToString(),
                                    AppDomain.CurrentDomain.Evidence,
                                    setup,
                                    AppDomain.CurrentDomain.PermissionSet);
//The following statement in theory should pick B.dll's dependency from DirA.
var assembly = domain.Load(AssemblyName.GetAssemblyName(@"C:\Root\DirB\B.dll").Name);
//Do the same in a different domain for C.dll

Thanks for any help on that.

Answer

paquetp picture paquetp · Aug 17, 2012

This looks like a job for the ResolveEventHandler (more detail on MSDN regarding resolving unknown assemblies)

So, you can write something like

class MyResolver
{
  public static Assembly MyResolveEventHandler( Object sender, ResolveEventArgs args )
  {
    // confirm args.Name contains A.dll
    String dllName = args.Name.Split({','}, SplitStringOptions.None)[0];
    if (dllName == "A")
    {
      return Assembly.LoadFile(@"C:\Root\DirA\A.dll")
    }
    return null;
  }
}

and in the domain you created, you'd do a:

domain.AssemblyResolve += new ResolveEventHandler(MyResolver.MyResolveEventHandler);

Make sure you bind the event before you reference A in B.