WebサイトまたはWindowsアプリのすべてのアセンブリで特定のタイプを探す必要がありますが、これを行う簡単な方法はありますか? ASP.NET MVCのコントローラーファクトリがコントローラーのすべてのアセンブリでどのように見えるかと同様です。
ありがとう。
これを達成するには、2つのステップがあります。
AppDomain.CurrentDomain.GetAssemblies()
は、現在のアプリケーションドメインにロードされたすべてのアセンブリを提供します。Assembly
クラスは、その特定のアセンブリ内のすべての型を取得するGetTypes()
メソッドを提供します。したがって、コードは次のようになります。
foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (Type t in a.GetTypes())
{
// ... do something with 't' ...
}
}
特定の型を探すには(たとえば、特定のインターフェイスの実装、共通の祖先からの継承など)、結果を除外する必要があります。アプリケーションの複数の場所でそれを行う必要がある場合、異なるオプションを提供するヘルパークラスを構築することをお勧めします。たとえば、名前空間プレフィックスフィルター、インターフェイス実装フィルター、および継承フィルターを一般的に適用しました。
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));
}
最も一般的なのは、外部から見えるアセンブリのみです。そのため、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;
}
}
}
}
}