0
votes

My application generates diagrams from the code structure of .NET applications. Assembly.LoadFile works, but only if my application has been put in the same folder as the assembly that I'm loading (seems to be due to referenced assemblies); if its not in the same folder, I get a ReflectionTypeLoadException exception if the loaded assembly had dependencies not in the GAC.

I've tried using Assembly.ReflectionOnlyLoadFrom instead.

AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += ResolveAssembly;
Assembly loadedAssembly = Assembly.ReflectionOnlyLoadFrom(FileName);

With the following event:

Assembly ResolveAssembly(object sender, ResolveEventArgs args){
    return Assembly.ReflectionOnlyLoad(args.Name);
}

But that ResolveAssembly only got called for System, System.Windows.Forms, and System.Drawing. It did not get called for OpenTK.dll, OpenTK.GLControl.dll and other referenced assemblies. And it too threw a ReflectionTypeLoadException when I called loadedAssembly.GetTypes().

How can I get it to load the referenced assemblies, so that I don't have to enforce my application be put in the same folder as the assembly its inspecting?

Update:

When I call Assembly.ReflectionOnlyLoadFrom, I can use GetReferencedAssemblies() to observe the references from that assembly. When I examine AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies(), I notice only a single assembly was loaded (the one originally specified). In otherwords, the referenced assemblies are simply not being loaded (despite the ReflectionOnlyAssemblyResolve hook).

1
perhaps they are loaded in a separate app domain? - animaonline

1 Answers

0
votes

The first thing you could try would be handling the AppDomain.CurrentDomain.AssemblyResolve event and resolving it yourself.

The second thing I might consider is spawning a second AppDomain with the bin / probe-path set as the target directory, and basically relocating the work inside of that AppDomain.

However, I would also put serious consideration into using a standalone loader, i.e. that isn't tied into the .NET runtime at all. In some similar work (inspecting assemblies that aren't really related to the app itself - just for information etc) I make a lot of use of IKVM.Reflection.dll, which allows you to create a separate Universe - it has the same basic API as regular reflection, but frankly it doesn't get as confused (plus it allows you to load assemblies for other target platforms, which is handy).