c# - Loading Dependent Assemblies Manually -
i have project loads multiple versions of same assembly using either assembly.load or assembly.loadfile. use assembly.createinstance create type specific assembly.
this works great until type i'm creating references dependent assembly. need way intercept specific assembly's request load assembly , provide correct version (or, better, probing path) dependency.
this required because v1 , v2 of assemblies i'm creating assembly.createinstance need different versions of dependent assemblies well, both v1 , v2 will, default, probe same directories.
i've seen examples of how appdomain, need in way handles resolution particular root assembly. assuming like:
appdomain.currentdomain.assemblyresolve += delegate(object sender, resolveeventargs args) { //use args.requestingassembly determine if v1 or v2 based on path or whatever //load correct dependent assembly args.requestinassembly console.writeline(args.name); return null; };
this may work dependencies referenced target assembly, assemblies dependencies reference? if v1 references depv1 references depdepv1, i'll need able know can ensure can find them properly.
in case, supposed need track somehow. perhaps adding custom assembly evidence - although haven't been able work, , there doesn't appear "assembly meta data" property can add @ runtime.
it far, far easier if instruct particular assembly load dependencies particular directory.
update
i managed use assemblyresolve event load dependent assemblies based on path of requestingassembly, seems flawed approach. seems though dependent assembly version while used entirely dependent on version happens 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 depv1 (works)
- code in v2 uses type depv2 <-- fails because gets type depv1!
i'm inferring steps 5 , 6 @ point, do see depv1 , depv2 being loaded.
as turns out, key making work ensure use assembly.loadfile. loadfile method load assembly if matches assembly .net thinks loaded. discovered article on codeproject.
since needed load 2 different assemblies both had identical full names (i.e. "app.test.domain, version=1.0.0.0, culture=neutral, publickeytoken=null") had different contents, loadfile way accomplish this. initial attempts used load overload accepted type assemblyname, ignore path defined in assemblyname instance , instead return loaded type.
to force entire dependency graph load specific location regardless of other types loaded register assemblyresolve event:
appdomain.currentdomain.assemblyresolve += resolvedependentassembly;
and ensure use loadfile load dependency:
private assembly resolvedependentassembly(object sender, resolveeventargs args) { var requestingassemblylocation = args.requestingassembly.location; if (thepathmatchessomerulesoiknowthisiswhatiwanttointercept) { var assemblyname = new assemblyname(args.name); string targetpath = path.combine(path.getdirectoryname(requestingassemblylocation), string.format("{0}.dll", assemblyname.name)); assemblyname.codebase = targetpath; //this alone won't force assembly load here! //we have use loadfile here, otherwise won't load differing //version, regardless of codebase because loadfile //will load *new* assembly if it's @ different path //see: http://msdn.microsoft.com/en-us/library/b61s44e8(v=vs.110).aspx return assembly.loadfile(assemblyname.codebase); } return null; }
yes, code assumes if root assembly has dependencies, they're located @ same path. that's limitation, no doubt, add additional hints non-local dependencies. issue if loaded version of additional dependencies wouldn't work.
lastly, none of necessary if assembly versions incremented. load call not treat loaded depv1 same request depv2. in case, wasn't willing deal part of continuous integration , deployment process.
Comments
Post a Comment