Cannot reflect over assembly that shares a dependency of different version
Here's the scenario using Assembly.ReflectionOnlyLoadFrom:
Both my assembly Inspected and my reflection Application Inspector reference Assembly Dependency.
If Inspector references Dependency 1.0.0.0 and Inspected references Dependency 1.1.0.0, 开发者_Python百科Inspector cannot reflect over any types or methods in Inspected that use a type from Dependency. The moment such a type is hit i get:
System.IO.FileLoadException: Could not load file or assembly 'Dependency, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
However, Inspector can reflect over Dependency 1.1.0.0 itself just fine, so loading Dependency 1.1.0.0 as Assembly.ReflectionOnlyLoadFrom does work from an assembly that's already using Dependency 1.0.0.0.
Here is the code i use to load an assembly and preload it's dependencies:
var assembly = Assembly.ReflectionOnlyLoadFrom(assemblyPath);
foreach (var assemblyName in assembly.GetReferencedAssemblies()) {
Assembly.ReflectionOnlyLoad(assemblyName.FullName);
}
It's not an issue with Dependency 1.1.0.0 not being resolved, as i've set a breakpoint in the foreach and confirmed it is loaded and also checked AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies() for its presence. It's loaded alright. But when i then do assembly.GetTypes(), it dies.
Is there something i can do about this, or do i have to reflect over assemblies in a separate AppDomain and marshall the meta data back into the appdomain that has a reference to Dependency 1.0.0.0?
In Customizing the .NET Framework Common Language Runtime , it is explained that Load and LoadFrom create separate "scopes" for loaded assemblies, which I guess explains the problem. Something to try is to find the assemblies yourself and load them all with LoadFrom.
Have you tried handling the AppDomain.AssemblyResolve event ?
I just hit this problem 11 years after the original question. Solved it by applying the current AppDomain policy to the assembly being loaded by reflection:
Assembly.ReflectionOnlyLoad(AppDomain.CurrentDomain.ApplyPolicy(args.Name));
Note in the app.config for the running application you will need a redirect like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Some.Dependency" publicKeyToken="someToken" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
精彩评论