views:

310

answers:

4

At runtime, if a referenced assembly fails to load with e.g. "Strong name validation failed" (because it's test-signed), is there a way to provide a substitution assembly from another path that is real-signed?

I tried subscribing to AppDomain.CurrentDomain.AssemblyResolve, but it doesn't get fired, because the "bad" assembly technically exists, it just can't be loaded.

Is there a generic way to provide a fallback assembly when an assembly can't be loaded?

+1  A: 

What triggers the load attempt? IOW do you call Assembly.Load or this is a result of type resolution attempt? If it is the latter you can try to play with the AppDomain TypeResolve event, if the former - you can add additional logic to your call to the Assembly.Load.

If you load the Assembly manually though make sure you load it with Assembly.Load - not Assembly.LoadFrom. There are subtle differences in type resolution depending on what context assembly is loaded into

mfeingold
I don't use Assembly.Load - the assembly in question is linked by the compiler. Whenever I start using the assembly - I call typeof(TypeInAssembly).GetTypes() - this loads the first assembly and recursively its unsigned referenced assembly.TypeResolve doesn't get raised either :(Thanks anyway.
Kirill Osenkov
+1  A: 

I think you can just call assembly.LoadFrom to load the assembly of your choice with practically no security checks. We us this a lot at the start of our app so we can better deal with other assemblies version change.

Also look at Assembly.LoadFrom Method (String, Evidence, Byte[], AssemblyHashAlgorithm) looks like you can control passing in the hash as well as the hash algorithm.

Aaron Fischer
Thanks. I just tried that and it gives me the same "Strong name validation failed" although I point it to the correct assembly:var assemblyName = AssemblyName.GetAssemblyName(correctFileName);var assembly = Assembly.Load(assemblyName);I'm thinking this is because the correctFileName is outside the app CodeBase folder.I guess I'll just leave it and go a different route...
Kirill Osenkov
with loadfrom you pass a file path and you can load the assembly from any where(pretty much).
Aaron Fischer
Yup, LoadFrom seemed to get me past this. I've hit other problems later, so I've scrapped the whole approach, but yes, this problem is solved. Preload the assemblies instead of responding to load failures. Thanks!
Kirill Osenkov
A: 

Looks like what I want is impossible. I decided to go another route. We'll have to modify the build system to conditionally link to signed binaries instead of test-signed binaries at compile time.

Thanks everyone for the suggestions though!

Kirill Osenkov
A: 

there is a standard way to find an assembly in case the application fails to do so:

// register on assembly resolve exception AppDomain.CurrentDomain.AssemblyResolve += ResolveEventHandler;

// try to load the assembly yourself private static Assembly ResolveEventHandler(object sender, ResolveEventArgs args) { return Assembly.Load(some_location); }

geva30