locked
Get namespaces from an assembly RRS feed

  • Question

  • Does anyone know how the Visual Studio 2005 object browser reads an assembly reference to list all the types and namespaces? I tried using reflection but it bails at Assembly.GetTypes(). I guess I have some dependency assemblies not installed on my system so it throws the "One or more classes in a module could not be loaded. " error. However, when I add this assembly as my project reference, the object browser is able to read through this assembly. Is there some trick to do that?

     Assembly a = Assembly.ReflectionOnlyLoadFrom(filePath);

    try

    {

    foreach (Type t in a.ManifestModule.GetTypes())

    {

    string nsp = t.Namespace;

    }

    }

    catch (Exception ex)

    {

    System.Diagnostics.Trace.WriteLine(ex.Message);

    }

    Friday, February 3, 2006 1:27 AM

Answers

  • When using ReflectionOnlyLoadFrom, you have to manually make sure that the Assembly's references have already been loaded or handle the AppDomain.ReflectionOnlyAssemblyResolve event and load them from there.

    I wrote a quick sample that loads all the namespaces of the System assembly, and then displays them to the console window:



    using System;
    using System.Reflection;
    using System.Collections.Generic;
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(OnAssemblyResolve);

                Assembly assembly = Assembly.ReflectionOnlyLoad("System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
     
                Type[] types = assembly.GetTypes();
     
                Dictionary<string, object> namespaces = new Dictionary<string, object>();
     
                object holder = new object();
     
                foreach (Type type in assembly.GetTypes())
                {
                    if (type.Namespace != null)
                    {
                        namespaces[type.Namespace] = holder;
                    }
                }
     
                foreach (string key in namespaces.Keys)
                {
                    Console.WriteLine(key);
                }
            }
     
            static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
            {
                return Assembly.ReflectionOnlyLoad(args.Name);
            }
        }
    }

     

    Hope that helps.

    David

    Friday, February 3, 2006 5:16 AM

All replies

  • While I cannot explain why ReflectionOnlyLoadFrom() doesn’t work as you’ve got it right now, replacing it with LoadFrom() does work... would that work for you?
    Friday, February 3, 2006 2:09 AM
  • When using ReflectionOnlyLoadFrom, you have to manually make sure that the Assembly's references have already been loaded or handle the AppDomain.ReflectionOnlyAssemblyResolve event and load them from there.

    I wrote a quick sample that loads all the namespaces of the System assembly, and then displays them to the console window:



    using System;
    using System.Reflection;
    using System.Collections.Generic;
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(OnAssemblyResolve);

                Assembly assembly = Assembly.ReflectionOnlyLoad("System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
     
                Type[] types = assembly.GetTypes();
     
                Dictionary<string, object> namespaces = new Dictionary<string, object>();
     
                object holder = new object();
     
                foreach (Type type in assembly.GetTypes())
                {
                    if (type.Namespace != null)
                    {
                        namespaces[type.Namespace] = holder;
                    }
                }
     
                foreach (string key in namespaces.Keys)
                {
                    Console.WriteLine(key);
                }
            }
     
            static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
            {
                return Assembly.ReflectionOnlyLoad(args.Name);
            }
        }
    }

     

    Hope that helps.

    David

    Friday, February 3, 2006 5:16 AM
  •  

    How about reading namespaces when dependency can not be resolved (missing on the local machine)?

    There is definitely a way because Lutz Roeder's Reflector can do that somehow, but i couldn't find any Sad

    Tuesday, August 21, 2007 5:55 PM