Comment prévenir ReflectionTypeLoadException lors de l'appel de l'Assemblée.GetTypes()
Je suis en train de scanner un assemblage de types de mise en oeuvre de l'interface à l'aide de code similaire à ceci:
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;
}
Mon problème est que je reçois un ReflectionTypeLoadException
lors de l'appel de asm.GetTypes()
dans certains cas, par exemple, si l'assemblée contient des types de la référence à une assemblée qui n'est pas disponible actuellement.
Dans mon cas, je ne suis pas intéressé par les types qui sont à l'origine du problème. Les types que je recherche, n'ont pas besoin de la non-disponible assemblées.
La question est: est-il possible de faire en quelque sorte sauter/ignorer les types qui cause de l'exception, mais encore à traiter les autres types de contenus dans l'assemblée?
- Il peut être beaucoup plus d'une réécriture de ce que vous cherchez, mais MEF vous donne des fonctionnalités similaires. Il suffit de marquer chacune de vos classes avec un [Exporter] balise qui spécifie l'interface elle met en œuvre. Ensuite, vous pouvez importer uniquement les interfaces qui vous intéresse en ce moment.
- Merci pour votre commentaire. Je pensais à l'aide de la MEF, mais je voulais voir si il y a une solution moins chère.
- Donner le plugin classe factory, un nom bien connu de sorte que vous pouvez simplement utiliser l'Activateur.CreateInstance() est une solution simple. Néanmoins, si vous obtenez cette exception à présent, en raison d'une résolution de l'assemblée problème, alors vous aurez probablement obtenir plus tard.
- Je ne suis pas sûr que je comprends parfaitement. L'assemblée, je suis la numérisation peut contenir n'importe quel nombre de types de mise en œuvre de l'interface donnée, donc il n'y a pas un type bien connu. (et aussi: je suis la numérisation de plus d'une assemblée, et non pas un seul)
- J'ai presque le même code, et le même problème. Et l'assemblée j'explore est donnée par
AppDomain.CurrentDomain.GetAssemblies()
, cela fonctionne sur ma machine mais pas sur d'autres machines. Pourquoi diable aurait quelques assemblées de mon exécutable de ne pas être lisibles/chargé de toute façon ??
Vous devez vous connecter pour publier un commentaire.
Un assez méchant serait:
C'est vraiment ennuyeux d'avoir à faire cela. Vous pouvez utiliser une méthode d'extension pour le rendre plus agréable dans le "client" code:
Pourraient bien vous souhaitez déplacer l'
return
déclaration du bloc catch - je ne suis pas terriblement vif sur elle d'être moi-même, mais il a probablement est les plus brefs code...From t As Type In e.Types Where (t IsNot Nothing) AndAlso (t.TypeInitializer IsNot Nothing)
Il semble fonctionner à merveille.Alors qu'il semble que rien ne peut être fait sans la réception de la ReflectionTypeLoadException à un certain point, les réponses ci-dessus sont limitées dans la mesure où toute tentative d'utiliser les types de condition de l'exception, vous pouvez toujours question d'origine avec le problème qui a causé le type d'échec du chargement.
Pour surmonter cette difficulté le code suivant limite les types que ceux situés au sein de l'assemblée et permet un prédicat pour restreindre la liste des types.
Avez-vous envisagé de De l'assemblée.ReflectionOnlyLoad ? Compte tenu de ce que vous essayez de faire, il peut être suffisant.
Dans mon cas, le même problème a été causé par la présence d'indésirables assemblées dans le dossier de l'application. Essayez d'effacer le dossier Bin et reconstruire l'application.