testalino
testalino

Reputation: 5658

Reflection: Assembly.GetExportedTypes requires all assemblies to be present

I want to analyze assemblies using reflection.

Specifically, I want to find out if a certain interface is implemented in a type in the assembly.

Not all references of the assembly are present on the machine though, which is why I need to analyze them.

So when I call GetTypes or GetExportedTypes, a FileNotFoundException is thrown, telling me that a "referenced assembly cannot be loaded".

This is true, but still I want to know what types are implemented in this assembly.

Reflector can do it somehow. How can this be done?

EDIT: I just found out about Mono.Cecil, does exactly what I want in an easy way. However, it is an external library and no built-in solution.

Upvotes: 3

Views: 4444

Answers (3)

ifitzgerald
ifitzgerald

Reputation: 21

I need to do the same thing, and after hours of searching, I came across this.

The code you need is at the bottom of the thread. It doesn't get you all the way, but it at least lets you get a list of all the types in an assembly even without having all of the dependencies.

EDIT: Here is the code snippet used in the referred link:

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(args.Name), AssemblyBuilderAccess.Run);
    _dumbAssemblies.Add(args.Name, ab);

    return ab;
}

private Dictionary<string, AssemblyBuilder> _dumbAssemblies;

What it does is create dumb assemblies for each assembly that is missing, so this avoids the FileNotFoundException from being thrown.

Upvotes: 2

kodybrown
kodybrown

Reputation: 2593

I had the same problem and figured this out:
Using Assembly.LoadFrom() instead of Assembly.LoadFile()

It works for me at least! :-)

Assembly asm;
Type[] types;

asm = Assembly.LoadFile(@"C:\path\assembly.dll");
types = asm.GetTypes() // throws FileNotFoundException.

asm = Assembly.LoadFrom(@"C:\path\assembly.dll");
types = asm.GetTypes() // Works!

Assembly.GetExportedTypes() behaves the same as above, too.

Upvotes: 2

John Doty
John Doty

Reputation: 3333

CCI might be kinda heavyweight for what you want, but it can reflect over assemblies without having them all loaded: http://cciast.codeplex.com/

Upvotes: 2

Related Questions