Estou tentando escanear um assembly em busca de tipos que implementam uma interface específica usando um código semelhante a este:
public List<Type> FindTypesImplementing<T>(string assemblyPath)
{
var matchingTypes = new List<Type>();
var asm = Assembly.LoadFrom(assemblyPath);
foreach (var t in asm.GetTypes())
{
if (typeof(T).IsAssignableFrom(t))
matchingTypes.Add(t);
}
return matchingTypes;
}
Meu problema é que recebo um ReflectionTypeLoadException
ao chamar asm.GetTypes()
em alguns casos, por exemplo, se o assembly contém tipos que fazem referência a um assembly que não está disponível no momento.
No meu caso, não estou interessado nos tipos que causam o problema. Os tipos que procuro não precisam de assemblies não disponíveis.
A questão é: é possível pular / ignorar de alguma forma os tipos que causam a exceção, mas ainda assim processar os outros tipos contidos na montagem?
AppDomain.CurrentDomain.GetAssemblies()
, isso funciona na minha máquina, mas não em outras máquinas. Por que diabos alguns assemblies do meu executável não podem ser lidos / carregados de qualquer maneira?Respostas:
Uma maneira bastante desagradável seria:
É definitivamente irritante ter que fazer isso. Você pode usar um método de extensão para torná-lo mais agradável no código do "cliente":
Você pode muito bem querer mover a
return
instrução para fora do bloco catch - eu não estou muito interessado em que ela esteja lá, mas provavelmente é o código mais curto ...fonte
From t As Type In e.Types Where (t IsNot Nothing) AndAlso (t.TypeInitializer IsNot Nothing)
Parece funcionar muito bem.Embora pareça que nada pode ser feito sem receber a ReflectionTypeLoadException em algum ponto, as respostas acima são limitadas, pois qualquer tentativa de utilizar os tipos fornecidos na exceção ainda apresentará problemas com o problema original que causou a falha no carregamento do tipo.
Para superar isso, o código a seguir limita os tipos àqueles localizados dentro do assembly e permite que um predicado restrinja ainda mais a lista de tipos.
fonte
Você já considerou Assembly.ReflectionOnlyLoad ? Considerando o que você está tentando fazer, pode ser o suficiente.
fonte
No meu caso, o mesmo problema foi causado pela presença de assemblies indesejados na pasta do aplicativo. Tente limpar a pasta Bin e reconstruir o aplicativo.
fonte