Getting a list of all available namespaces in an AppDomain
Asked Answered
I

2

5

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.

Inaugural answered 20/2, 2013 at 9:39 Comment(2)
If you just started learning C#, save reflection and other advanced stuff for later. My opinion of course.Sterner
I have been working with c/c++ and assembly for the past 20 years, so I'm not a complete noob, gotta start somewhere :)Inaugural
A
2

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!

Acetone answered 20/2, 2013 at 9:47 Comment(0)
B
6

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();
Broderickbrodeur answered 20/2, 2013 at 9:43 Comment(0)
A
2

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!

Acetone answered 20/2, 2013 at 9:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.