I have a project that loads multiple versions of the same assembly using either Assembly.Load or Assembly.LoadFile. I then use Assembly.CreateInstance to create a type from that specific assembly.
This works great until the type I'm creating references another dependent assembly. I need a way to intercept this specific assembly's request to load another assembly and provide it with the correct version (or, even better, probing path) to look for its dependency.
This is required because v1 and v2 of the assemblies I'm creating with Assembly.CreateInstance will often need different versions of their dependent assemblies as well, but both v1 and v2 will, by default, probe the same directories.
I've seen examples of how to do generally for an AppDomain, but I need to do this in a way that handles all resolution from a particular root assembly. Assuming I do something like:
AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs args)
{
//Use args.RequestingAssembly to determine if this is v1 or v2 based on path or whatever
//Load correct dependent assembly for args.RequestinAssembly
Console.WriteLine(args.Name);
return null;
};
This may work for dependencies immediately referenced by my target assembly, but what about the assemblies that those dependencies reference? If v1 references Depv1 which itself references DepDepv1, I'll need to be able to know this so I can ensure it can find them properly.
In that case, I supposed I would need to track this somehow. Perhaps by adding custom assembly evidence - although I haven't been able to get that to work, and there doesn't appear to be any "assembly meta data" property that I can add to at runtime.
It would be far, far easier if I could simply instruct a particular assembly to load all its dependencies from a particular directory.
Update
I managed to use the AssemblyResolve event to load the dependent assemblies based on the path of the RequestingAssembly, but it seems to be a flawed approach. It seems as though the which dependent assembly version while be used is entirely dependent on which version happens to be loaded first.
For instance:
- Load v1
- Load v2
- Reference v1 causes load of Depv1
- Reference v2 causes load of Depv2
- Code in v1 uses type from Depv1 (Works)
- Code in v2 uses type from Depv2 <-- fails because it gets type from Depv1!
I'm only inferring steps 5 and 6 at this point, but I do see Depv1 AND Depv2 being loaded.