Ich schätze, dass dies eine sehr alte Frage ist, aber ich dachte, ich würde eine weitere Antwort für zukünftige Benutzer hinzufügen, da alle bisherigen Antworten irgendeine Form von verwenden Assembly.GetTypes
.
GetTypes () gibt zwar alle Typen zurück, bedeutet jedoch nicht unbedingt, dass Sie sie aktivieren und somit möglicherweise a auslösen können ReflectionTypeLoadException
.
Ein klassisches Beispiel dafür, dass ein Typ nicht aktiviert werden kann, ist, wenn der zurückgegebene Typ derived
von stammt, base
aber base
in einer anderen Assembly als der von derived
einer Assembly definiert ist, auf die die aufrufende Assembly nicht verweist.
Sagen wir also, wir haben:
Class A // in AssemblyA
Class B : Class A, IMyInterface // in AssemblyB
Class C // in AssemblyC which references AssemblyB but not AssemblyA
Wenn in ClassC
was AssemblyC
drin ist, dann tun wir etwas gemäß der akzeptierten Antwort:
var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
Dann wird es ein werfen ReflectionTypeLoadException
.
Dies liegt daran, dass Sie ohne einen Verweis auf AssemblyA
in AssemblyC
nicht in der Lage wären:
var bType = typeof(ClassB);
var bClass = (ClassB)Activator.CreateInstance(bType);
Mit anderen Worten ClassB
ist nicht ladbar das ist etwas, dass der Aufruf von GetTypes Kontrollen und wirft auf.
Um die Ergebnismenge sicher für ladbare Typen zu qualifizieren, führen Sie stattdessen gemäß diesem Phil Haacked- Artikel Get All Types in a Assembly und Jon Skeet-Code Folgendes aus :
public static class TypeLoaderExtensions {
public static IEnumerable<Type> GetLoadableTypes(this Assembly assembly) {
if (assembly == null) throw new ArgumentNullException("assembly");
try {
return assembly.GetTypes();
} catch (ReflectionTypeLoadException e) {
return e.Types.Where(t => t != null);
}
}
}
Und dann:
private IEnumerable<Type> GetTypesWithInterface(Assembly asm) {
var it = typeof (IMyInterface);
return asm.GetLoadableTypes().Where(it.IsAssignableFrom).ToList();
}