获取 AppDomain 中所有可用命名空间的列表

Posted

技术标签:

【中文标题】获取 AppDomain 中所有可用命名空间的列表【英文标题】:Getting a list of all available namespaces in an AppDomain 【发布时间】:2013-02-20 09:39:57 【问题描述】:

我需要在运行时“扫描”所有已加载程序集的活动 AppDomain 并获取这些程序集中可用的唯一命名空间列表,.NET 是否支持?

代码必须在运行时执行,这样代码是动态的。

我刚开始用 C# 编码,所以我有点不确定从哪里开始,所以任何帮助都将不胜感激。

【问题讨论】:

如果您刚开始学习 C#,请保存反射和其他高级内容以备后用。当然是我的意见。 在过去的 20 年里我一直在使用 c/c++ 和汇编,所以我不是一个完全的菜鸟,必须从某个地方开始 :) 【参考方案1】:

AppDomain(可能是AppDomain.CurrentDomain)开始并调用GetAssemblies。在每个程序集上迭代它定义的types,跟踪每个程序集所在的namespace。

作为一个使用 LINQ 轻松完成此操作的示例,请考虑以下内容:

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】:

事实上,我在几天前写了一些代码,可以让你这样做。

使用这个类

    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;
        
    

用法

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

享受吧!

【讨论】:

以上是关于获取 AppDomain 中所有可用命名空间的列表的主要内容,如果未能解决你的问题,请参考以下文章

如何获取所有使用的命名空间的列表?

在C#中获取命名空间中的类列表[重复]

Vuex,命名空间的模块获取器在根获取器中不可用?

取出特定命名空间的所有类

从 AppDomain 获取静态列表

C ++:使类及其某些数据成员仅在命名空间中可用