c# - AssemblyResolve event fires when calling Assembly.Load(byte()) -
so have wpf project pulling in dlls used project here @ job. it's mess of dependencies, i've been using technique here: http://www.digitallycreated.net/blog/61/combining-multiple-assemblies-into-a-single-exe-for-a-wpf-application embed dependencies single executable.
now, when i'm calling specific method inside 1 of dependencies, hit assemblyresolve event. onresolveassembly event runs, finds assembly embedded resource (cool!), , "return assembly.load(assembyrawbytes)". if hit f11 @ point (with breakpoint @ beginning of onresolveassembly), another call same event. it's same assembly (args.name same).
if let run hit stack overflow, since can never seem escape recursive event calling.
the msdn docs don't when assembly.load can fail, except filenotfoundexception or badimageformatexception.
i've tried unhooking onresolveassembly @ moment before call assembly.load, application dies mysterious death, under vs goes poof.
i'm breaking several rules here, ideas of start looking problems welcome.
i'm going start poking around in problematic dll see if there hints wrong (maybe it's mixed assembly?).
here's onresolveassembly handler:
private static assembly onresolveassembly(object sender, resolveeventargs args) { assembly executingassembly = assembly.getexecutingassembly(); assemblyname assemblyname = new assemblyname(args.name); string path = assemblyname.name + ".dll"; if (assemblyname.cultureinfo.equals(system.globalization.cultureinfo.invariantculture) == false) { path = string.format(@"{0}\{1}", assemblyname.cultureinfo, path); } using (stream stream = executingassembly.getmanifestresourcestream(path)) { if (stream == null) return null; byte[] assemblyrawbytes = new byte[stream.length]; stream.read(assemblyrawbytes, 0, assemblyrawbytes.length); assemblydictionary.add(assemblyname.name, assembly.load(assemblyrawbytes)); return assemblydictionary[assemblyname.name]; } }
for time being, i've resolved iterating through of resources , attempting assembly.load on them, , storing them in dictionary retrieval (during onresolveassembly event):
[stathread] public static void main() { appdomain.currentdomain.assemblyresolve += onresolveassembly; assembly executingassembly = assembly.getexecutingassembly(); string[] resources = executingassembly.getmanifestresourcenames(); foreach (string resource in resources) { if (resource.endswith(".dll")) { using (stream stream = executingassembly.getmanifestresourcestream(resource)) { if (stream == null) continue; byte[] assemblyrawbytes = new byte[stream.length]; stream.read(assemblyrawbytes, 0, assemblyrawbytes.length); try { assemblydictionary.add(resource, assembly.load(assemblyrawbytes)); } catch (exception ex) { system.diagnostics.debug.print("failed load: " + resource + " exception: " + ex.message); } } } } app.main(); } private static assembly onresolveassembly(object sender, resolveeventargs args) { assembly executingassembly = assembly.getexecutingassembly(); assemblyname assemblyname = new assemblyname(args.name); string path = assemblyname.name + ".dll"; if (assemblydictionary.containskey(path)) { return assemblydictionary[path]; } return null; }
it seems working fine (the "failing" assembly load fine in second snippet), i'd interested learn why doesn't work in first.
loading assembly byte[] way end in .dll hell (the place go many/complex dependencies). problem here although loaded dll appdomain not automatically resolved, when need again dependent types. commented on problem here: assemblyresolve not fire
long story short, assemblies loaded different "contexts" inside of appdomains. context used load(byte[]) not resolve assemblies automatically.
the solution keeping track of loaded assemblies , returning loaded assembly instead of loading second time. there starting point approach in answer to: need hookup assemblyresolve event when disallowapplicationbaseprobing = true
but think got right workaround.
btw. loading assembly twice way identical incompatible types. ever cast object of mytype myassembly mytype same assembly , got null?
that's warm "welcome .dll hell".
Comments
Post a Comment