6

我想遍历我在项目中添加的所有类

Assembly[] foo = AppDomain.CurrentDomain.GetAssemblies();

foreach(Assembly a in foo)
{                
    foreach(Type t in a.GetTypes())
    {

    }
}

这是我尝试过的,但我想排除 .net 提供的程序集,例如“mscorlib”

4

3 回答 3

10

如果您的所有程序集都有一个共同的前缀(如果您有或多或少的唯一前缀),一种常见的解决方案是按名称过滤程序集。

var foo = AppDomain.CurrentDomain.GetAssemblies()
                                 .Where(a=>a.FullName.StartsWith("MyProject."));

如果您只对某些特定类型感兴趣,请考虑为您的类使用属性,甚至在程序集级别添加一个。

例子:

创建一个属性:

[AttributeUsage(AttributeTargets.Assembly)]
public class MyAssemblyAttribute : Attribute { }

将以下内容添加到您的 AssemblyInfo.cs:

[assembly: MyAssemblyAttribute()]

并过滤您正在查看的程序集:

var foo = AppDomain.CurrentDomain
                   .GetAssemblies()
                   .Where(a => a.GetCustomAttributes(typeof(MyAssemblyAttribute), false).Any());

你也会发现这个问题很有趣。在一个答案中,建议检查每个程序集的完全限定名称,但这非常乏味,例如:

//add more .Net BCL names as necessary
var systemNames = new HashSet<string>
{
    "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
    "System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
    ...
};

var isSystemType = systemNames.Contains(objToTest.GetType().Assembly.FullName); 

标记您的程序集(按名称或属性)总是比尝试识别哪些是 .Net 框架的一部分更容易。

于 2012-06-04T13:03:23.573 回答
1

在我的一个项目中,我需要一个用作业务对象的类列表。这些类始终是用户创建的类型,但可以在引用的程序集中。它们不实现特定的接口,不从特定的基类派生,也没有独特的属性。

这是我用来过滤有用类型的代码:

return
    type.IsClass && // I need classes
    !type.IsAbstract && // Must be able to instantiate the class
    !type.IsNestedPrivate && // Nested private types are not accessible
    !type.Assembly.GlobalAssemblyCache && // Excludes most of BCL and third-party classes
    type.Namespace != null && // Yes, it can be null!
    !type.Namespace.StartsWith("System.") && // EF, for instance, is not in the GAC
    !type.Namespace.StartsWith("DevExpress.") && // Exclude third party lib
    !type.Namespace.StartsWith("CySoft.Wff") && // Exclude my own lib
    !type.Namespace.EndsWith(".Migrations") && // Exclude EF migrations stuff
    !type.Namespace.EndsWith(".My") && // Excludes types from VB My.something
    !typeof(Control).IsAssignableFrom(type) && // Excludes Forms and user controls
    type.GetCustomAttribute<CompilerGeneratedAttribute>() == null && // Excl. compiler gen.
    !typeof(IControllerBase).IsAssignableFrom(type); // Specific to my project

由于我的用户类型不在 GAC中,因此!type.Assembly.GlobalAssemblyCache在排除大多数 BCL(框架库)类型和一些第三方内容方面做得很好。

这不是无懈可击的,但我的情况很好。您很可能需要根据需要对其进行调整。

于 2017-08-11T17:53:12.073 回答
0

检查 Type in inner loop 的以下属性。

t.GetType().Namespace == "System"
t.GetType().Namespace.StartsWith("System")
t.GetType().Module.ScopeName == "CommonLanguageRuntimeLibrary"
于 2012-06-04T13:00:41.703 回答