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 derivedvon stammt, baseaber basein einer anderen Assembly als der von derivedeiner 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 ClassCwas AssemblyCdrin 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 AssemblyCnicht in der Lage wären:
var bType = typeof(ClassB);
var bClass = (ClassB)Activator.CreateInstance(bType);
Mit anderen Worten ClassBist 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();
}