J'apprécie que c'est une très vieille question, mais j'ai pensé ajouter une autre réponse aux futurs utilisateurs car toutes les réponses à ce jour utilisent une forme de Assembly.GetTypes .
Bien que GetTypes () renvoie en effet tous les types, cela ne signifie pas nécessairement que vous pouvez les activer et donc potentiellement lancer un ReflectionTypeLoadException.
Un exemple classique pour ne pas pouvoir activer un type serait lorsque le type retourné est derivedde basemais baseest défini dans un assembly différent de celui de derived, un assembly que l'assembly appelant ne référence pas.
Alors disons que nous avons:
Class A // in AssemblyA
Class B : Class A, IMyInterface // in AssemblyB
Class C // in AssemblyC which references AssemblyB but not AssemblyA
Si dans ClassClequel se trouve AssemblyCnous faisons alors quelque chose selon la réponse acceptée:
var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
Ensuite, il lancera un ReflectionTypeLoadException.
En effet , sans référence à AssemblyA en AssemblyCvous ne seriez pas en mesure de:
var bType = typeof(ClassB);
var bClass = (ClassB)Activator.CreateInstance(bType);
En d'autres termes ClassBn'est pas chargeable ce qui est quelque chose que l'appel à GetTypes vérifie et lance.
Donc, pour qualifier en toute sécurité l'ensemble de résultats pour les types chargeables, conformément à cet article de Phil Haacked Obtenir tous les types dans un code Assembly et Jon Skeet, vous devriez plutôt faire quelque chose comme:
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);
}
}
}
Et alors:
private IEnumerable<Type> GetTypesWithInterface(Assembly asm) {
var it = typeof (IMyInterface);
return asm.GetLoadableTypes().Where(it.IsAssignableFrom).ToList();
}