2011-01-14 59 views
47

我需要在网站或Windows应用程序的所有程序集中查找特定类型,是否有一种简单的方法可以执行此操作?就像ASP.NET MVC的控制器工厂在控制器的所有组件中查找一样。在所有程序集中查找类型

谢谢。

回答

79

有两个步骤来实现:

  • AppDomain.CurrentDomain.GetAssemblies()让你在当前的应用程序域中加载的所有程序集。
  • Assembly类提供了一个GetTypes()方法来检索该特定程序集内的所有类型。

因此你的代码可能是这样的:

foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) 
{ 
    foreach (Type t in a.GetTypes()) 
    { 
     // ... do something with 't' ... 
    } 
} 

为了寻找特定类型(例如实现给定的接口,从一个共同的祖先或任何继承),你必须筛选出的结果。如果您需要在应用程序的多个位置执行该操作,建立一个提供不同选项的助手类是一个不错的主意。例如,我通常应用名称空间前缀过滤器,接口实现过滤器和继承过滤器。

有关详细的文档,请查看MSDN herehere。与检查

IEnumerable<Type> types = 
      from a in AppDomain.CurrentDomain.GetAssemblies() 
      from t in a.GetTypes() 
      select t; 

foreach(Type t in types) 
{ 
    ... 
} 
+0

当然,如果你打算对这些类型和程序集做一些过滤,你会使用LINQ,对吧? ;) – 2011-01-14 15:54:51

26

易。因此,您需要致电GetExportedTypes()但除此之外,还可以抛出ReflectionTypeLoadException。以下代码处理这些情况。

public static IEnumerable<Type> FindTypes(Func<Type, bool> predicate) 
{ 
    if (predicate == null) 
     throw new ArgumentNullException(nameof(predicate)); 

    foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) 
    { 
     if (!assembly.IsDynamic) 
     { 
      Type[] exportedTypes = null; 
      try 
      { 
       exportedTypes = assembly.GetExportedTypes(); 
      } 
      catch (ReflectionTypeLoadException e) 
      { 
       exportedTypes = e.Types; 
      } 

      if (exportedTypes != null) 
      { 
       foreach (var type in exportedTypes) 
       { 
        if (predicate(type)) 
         yield return type; 
       } 
      } 
     } 
    } 
} 
19

LINQ的解决方案,看是否装配是动态的:

/// <summary> 
/// Looks in all loaded assemblies for the given type. 
/// </summary> 
/// <param name="fullName"> 
/// The full name of the type. 
/// </param> 
/// <returns> 
/// The <see cref="Type"/> found; null if not found. 
/// </returns> 
private static Type FindType(string fullName) 
{ 
    return 
     AppDomain.CurrentDomain.GetAssemblies() 
      .Where(a => !a.IsDynamic) 
      .SelectMany(a => a.GetTypes()) 
      .FirstOrDefault(t => t.FullName.Equals(fullName)); 
} 
4

最常见的是你只在那些从外部可见的组件兴趣使用LINQ

相关问题