Je cherche à analyser un assemblage à la recherche de types implémentant une interface spécifique en utilisant un code similaire à celui-ci :
public List FindTypesImplementing(string assemblyPath)
{
var matchingTypes = new List();
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 j'obtiens une ReflectionTypeLoadException
lors de l'appel de asm.GetTypes()
dans certains cas, par exemple si l'assemblage contient des types faisant référence à un assemblage qui n'est actuellement pas disponible.
Dans mon cas, je ne suis pas intéressé par les types qui posent problème. Les types que je recherche n'ont pas besoin des assemblages non disponibles.
La question est : est-il possible de passer/ignorer d'une manière ou d'une autre les types qui provoquent l'exception tout en traitant quand même les autres types contenus dans l'assemblage ?
1 votes
Il peut s'agir de bien plus qu'une simple réécriture de ce que vous recherchez, mais MEF vous offre une fonctionnalité similaire. Il vous suffit de marquer chacune de vos classes avec une balise [Export] qui spécifie l'interface qu'elle implémente. Ensuite, vous pourrez importer uniquement les interfaces qui vous intéressent à ce moment-là.
0 votes
@Drew, Merci pour votre commentaire. Je pensais à utiliser MEF, mais je voulais voir s'il y avait une autre solution moins chère.
0 votes
Donner à la classe factory du plugin un nom bien connu afin que vous puissiez simplement utiliser Activator.CreateInstance() directement est une solution de contournement simple. Néanmoins, si vous obtenez cette exception maintenant en raison d'un problème de résolution d'assembly, vous l'obtiendrez probablement aussi plus tard.
1 votes
@Hans: Je ne suis pas sûr de comprendre complètement. L'assembly que je suis en train de scanner pourrait contenir un nombre quelconque de types implémentant l'interface donnée, il n'y a donc pas un type bien connu. (et aussi: Je scanne plusieurs assemblies, pas seulement un)
2 votes
J'ai presque le même code, et le même problème. Et l'assembly que j'explore est donné par
AppDomain.CurrentDomain.GetAssemblies()
, cela fonctionne sur ma machine mais pas sur d'autres machines. Pourquoi diable certaines assemblies de mon exécutable ne seraient-elles pas lisibles/chargées de toute façon ??