2011-04-12 5 views
19

나는 높거나 낮은 것을 검색했지만, 이것에 대한 해결책을 찾을 수는 없습니다."안전하게"호출하는 방법 assembly.GetTypes()?

나는 다음과 같은 코드의 어셈블리에서 모든 인터페이스 유형을 얻을 필요가 :

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

이 문제는 특정 어셈블리에 대해 나는 다음과 같은 오류로 실행 :

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

나 ' 이 문제가 발생하는 이유 (종속 어셈블리가로드되지 않음)와 특정 어셈블리의 문제를 해결하려는 경우 어떻게 처리 할 수 ​​있는지 명확히 설명합니다. 필자의 경우 어셈블리를 앞쪽으로 (사용자가 선택할 것임) 알지 못합니다.

내가 알고 싶은 것은 코드를 검색 할 수없는 모든 유형에서 코드를 계속 진행할 수 있는지, 그리고 여전히 실패하지 않는 코드를 가져올 수 있는지 여부입니다.

답변

28

예외를 피할 수없는 고생하는 API 인 것처럼 보입니다 (아는 한). 이 같은

시도 뭔가 :

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

UPDATE

사실이 그래서 아마 어딘가에 숨겨 추한입니다. 이것은 .NET Framework의 아주 오래된 부분입니다. 왜냐하면 저는 요즘처럼 이런 디자인을하지 않을 것이라고 확신하기 때문입니다.

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); 

매우 자주 수행 할 것으로 생각되면 확장 방법이 더 적절할 수 있습니다.

+0

아주 구체적인 용도 (코드 생성)로 이것을 사용하십시오. 그 예외와 Types 속성을 알지 못했습니다. 완전한! –

+0

정말 고마워요! 우리는 아주 오랜 시간 동안이 성가신 오류에 시달려 왔습니다. –

0

람다 식 대신에 예외를 처리하고 예외를 catch합니다. 나중에 검사를 위해 전역 개체에 예외가 누적 될 수도 있습니다.

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; 
}