2011-01-14 54 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

相關問題