5
votes

I need to 'scan' the active AppDomain for all loaded assemblies at run time and get a list of unique namespaces available in those assemblies, does .NET support that?

The code must execute during the run time, so that the code is dynamic.

I just started coding in C# , so I'm a bit unsure about where to get started, so any help will be appreciated.

2
If you just started learning C#, save reflection and other advanced stuff for later. My opinion of course.gdoron is supporting Monica
I have been working with c/c++ and assembly for the past 20 years, so I'm not a complete noob, gotta start somewhere :)jjdev80

2 Answers

5
votes

Start from an AppDomain (AppDomain.CurrentDomain perhaps) and call GetAssemblies. On each assembly iterate over the types it defines, keeping track of which namespace each one is in.

As an example of how easy it is to do this with LINQ consider this:

var namespaces = AppDomain.CurrentDomain
                     .GetAssemblies()
                     .SelectMany(a => a.GetTypes())
                     .Select(t => t.Namespace)
                     .Distinct()
                     // optionally .OrderBy(ns => ns) here to get sorted results
                     .ToList();
2
votes

As a matter of fact I wrote some code that lets you do that a couple of days ago.

Use this class:

    public class NSScanner
    {
        public static List<Type> GetLoadedTypes(AppDomain appDomain)
        {
            return _getLoadedTypes(appDomain);
        }

        public static List<Type> GetPublicLoadedTypes(AppDomain appDomain)
        {
            return _getLoadedTypes(appDomain, true);
        }

        public static List<string> GetUniqueNamespaces(IEnumerable<Type> types)
        {
            var uniqueNamespaces = new ConcurrentBag<string>();

            Parallel.ForEach(types, type =>
            {
                if (!uniqueNamespaces.Contains(type.Namespace) && !string.IsNullOrEmpty(type.Namespace))
                    uniqueNamespaces.Add(type.Namespace);
            });

            var sortedList = uniqueNamespaces.OrderBy(o => o).ToList();

            return sortedList;
        }


        private static List<Type> _getLoadedTypes(AppDomain appDomain, bool onlyPublicTypes = false)
        {
            var loadedAssemblies = appDomain.GetAssemblies();

            var loadedTypes = new List<Type>();

            Parallel.ForEach(loadedAssemblies, asm =>
            {
                Type[] asmTypes;
                if (onlyPublicTypes)
                    asmTypes = asm.GetExportedTypes();
                else
                    asmTypes = asm.GetTypes();

                loadedTypes.AddRange(asmTypes);
            });

            return loadedTypes;
        }
    }

Usage:

var publicLoadedTypes = NSScanner.GetPublicLoadedTypes(AppDomain.CurrentDomain);
var namespaces = NSScanner.GetUniqueNamespaces(publicLoadedTypes);

Enjoy!