Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ignore missing dependencies during ReflectionOnlyLoad

I am working on a simple class browser dialog that allows users to open an assembly and choose a static method from within. However, there are some situations where the assembly's dependencies are missing.

Since I only need the method name and not its full prototype, is there any way to get past the FileNotFoundException that is raised when calling Assembly.ReflectionOnlyLoadFrom? I am currently handling AppDomain.ReflectionOnlyAssemblyResolve but if I return null then I get a FileLoadException with the following message:

Cannot resolve dependency to assembly '...' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.

I know this must be possible somehow because .NET Reflector allows you to skip unresolved dependencies. However I'm starting to think that maybe Reflector parses the assemblies manually rather than loading it into the CLR and using standard reflection. Perhaps it uses something like Cecil from the Mono project.

like image 438
Nathan Baulch Avatar asked Aug 27 '09 06:08

Nathan Baulch


3 Answers

I'd try Cecil if you're going to be doing non-trivial work with assemblies. There's also the MS CCI. (I'm not 100% sure either of these work with bits missing, but they're certainly good tools in this space and I'd be surprised if they didnt)

If you really need to get to the metal, you can't beat this Asmex tutorial and sample, which should defintely either work or let you work around it.

like image 72
Ruben Bartelink Avatar answered Nov 13 '22 13:11

Ruben Bartelink


This will ignore your missing dependencies:

        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(CurrentDomain_ReflectionOnlyAssemblyResolve);
            Assembly assembly = Assembly.ReflectionOnlyLoad("foo");
            foreach (Type t in assembly.GetTypes())
            {
                Console.WriteLine(t.FullName);
            }
        }

        static Assembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
        {
            return System.Reflection.Assembly.ReflectionOnlyLoad(args.Name);
        }
like image 35
David Montgomery Avatar answered Nov 13 '22 14:11

David Montgomery


I believe that Reflector does its own assembly parsing/loading - I looked at its source a while back (by using Reflector itself :p) and saw a large number of assembly-related classes, which seem to be parsed into a massive tree structure.

You could always email Red Gate/Rutz Loeder and ask them for definitive confirmation. :)

like image 28
Ian Kemp Avatar answered Nov 13 '22 14:11

Ian Kemp