aprecio esta es una pregunta muy antigua pero pensé que me gustaría añadir otra respuesta para los futuros usuarios como todas las respuestas hasta la fecha usan alguna forma de Assembly.GetTypes
.
Si bien GetTypes() devolverá todos los tipos, no significa necesariamente que pueda activarlos y, por lo tanto, podría arrojar un ReflectionTypeLoadException
.
Un ejemplo clásico por no ser capaz de activar un tipo sería cuando el tipo devuelto es derived
de base
pero base
se define en un conjunto diferente de la de derived
, un conjunto que el conjunto de la llamada no referencia.
Así que decir que tenemos:
Class A // in AssemblyA
Class B : Class A, IMyInterface // in AssemblyB
Class C // in AssemblyC which references AssemblyB but not AssemblyA
Si en ClassC
que está en AssemblyC
que luego hacer algo como respuesta aceptada por:
var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
entonces será lanzar una ReflectionTypeLoadException
.
Esto es porque sin una referencia a AssemblyA
en AssemblyC
que no sería capaz de:
var bType = typeof(ClassB);
var bClass = (ClassB)Activator.CreateInstance(bType);
En otras palabras ClassB
no es cargable que es algo que la llamada a getTypes cheques y arroja sobre.
Así que para calificar de manera segura el conjunto de resultados para los tipos que se pueden cargar a continuación, según esta Phil Haacked artículo Get All Types in an Assembly y Jon Skeet code debe en su lugar hacer algo como:
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);
}
}
}
Y luego:
private IEnumerable<Type> GetTypesWithInterface(Assembly asm) {
var it = typeof (IMyInterface);
return asm.GetLoadableTypes().Where(it.IsAssignableFrom).ToList();
}
¿Funciona el código de ejemplo?Tengo falsos negativos con tu condición if. –
La sentencia if en el código anterior siempre será falsa porque está probando si una instancia de la clase Type (t) implementa su interfaz, lo que no sucederá a menos que Type herede IMyInterface (en cuyo caso siempre será verdadera). – Liazy