2011-04-12 12 views
19

He buscado alto y bajo, pero no puedo encontrar una solución para esto.Cualquier forma de llamar "con seguridad" al conjunto de llamada.GetTypes()?

que necesito para obtener todos los tipos de interfaz de un conjunto con código como este:

IEnumerable<Type> interfaces = _assembly.GetTypes().Where(x => x.IsInterface); 

El problema es, para ciertos montajes me encuentro con el siguiente error:

Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.

I' Estoy completamente seguro de por qué sucede esto (los ensamblajes dependientes no están cargados) y cómo se puede solucionar si quiero solucionar un ensamblaje específico. En mi caso, no sé el ensamblaje por adelantado (el usuario lo seleccionará).

Lo que me gustaría saber es si hay alguna forma de permitir que el código continúe más allá de cualquier tipo que no se pueda recuperar, y aún así extraer los que no fallen.

Respuesta

28

Parece que esta es una API molesta para la cual no se puede evitar la excepción (que yo sepa).

intentar algo como esto:

IEnumerable<Type> interfaces; 
try 
{ 
    interfaces = _assembly.GetTypes().Where(x => x.IsInterface); 
} 
catch (ReflectionTypeLoadException ex) 
{ 
    interfaces = ex.Types.Where(x => x != null && x.IsInterface); 
} 

ACTUALIZACIÓN

En realidad, esto es tan fea que probablemente me ocultarlo en alguna parte. Esta debe ser una parte muy antigua de .NET Framework, porque estoy bastante seguro de que no lo diseñarían así hoy en día.

private static IEnumerable<Type> GetTypesSafely(Assembly assembly) 
{ 
    try 
    { 
     return assembly.GetTypes(); 
    } 
    catch(ReflectionTypeLoadException ex) 
    { 
     return ex.Types.Where(x => x != null); 
    } 
} 

... 
IEnumberable<Type> interfaces = GetTypesSafely(_assembly).Where(x => x.IsInterface); 

Si crees que vas a hacer esto muy a menudo, entonces un método de extensión podría ser más apropiado.

+0

Utilizándolo para un propósito muy específico (generación de código). No estaba al tanto de esa excepción y de la propiedad Tipos. ¡Perfecto! –

+0

muchas gracias! Hemos estado plagados por este molesto error durante mucho tiempo –

0

Maneje la excepción en otro método que tome el lugar de la expresión lambda y capture la excepción. También podría hacer que las excepciones se acumulen en algún objeto global para su posterior inspección.

IEnumerable<Type> interfaces = _assembly.GetTypes().Where(IsInterface); 

List<string> Messages = new List<string>(); 

private bool IsInterface(Type x) 
{ 
    try { return x.IsInterface; } 
    catch (Exception e) 
    { 
     Messages.Add(e.Message); 
    } 
    return false; 
} 
Cuestiones relacionadas