查找所有程序集中的类型

我需要在一个网站或窗口应用程序的所有程序集中寻找特定类型,是否有一个简单的方法来做到这一点?例如 ASP.NET MVC 的控制器工厂在所有控制器程序集中的外观。

谢谢。

62495 次浏览

实现这一目标有两个步骤:

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

因此,您的代码可能如下所示:

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

为了寻找特定的类型(例如,实现一个给定的接口,从一个共同的祖先或其他继承) ,您必须过滤掉结果。如果需要在应用程序的多个位置执行此操作,最好构建一个提供不同选项的 helper 类。例如,我通常应用名称空间前缀过滤器、接口实现过滤器和继承过滤器。

有关详细文档,请参阅 MSDN给你给你

简单使用 Linq:

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


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

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));
}

最常见的情况是,您只对从外部可见的程序集感兴趣。因此,你需要调用 出口类型(),但除此之外,一个 RefectionTypeLoadException可以抛出。下面的代码处理这些情况。

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;
}
}
}
}
}