2009-12-18 3 views
1

Je dois permettre aux utilisateurs un moyen facile d'identifier un type dans un assembly, puis obtenir l'objet Type correspondant.Besoin d'un moyen rapide de trouver un type basé sur son nom complet

Je pourrais, hypothétiquement, exiger qu'ils me donnent un assembly qualified name, mais c'est un peu klunky, et peut être difficile à comprendre si l'assemblée est signée. Ce serait plus facile de ma part, cependant, car je pourrais utiliser Type.GetType(string) pour obtenir mon objet de type.

Si j'autorise mes utilisateurs à me fournir un nom de type qualifié pour l'espace de noms (Namespace.Type), je ne peux pas utiliser Type.GetType pour rechercher mon objet type. Ce qui m'amène à ma question. Pour autant que je sache, la seule façon de faire est de spelunk à travers l'AppDomain actuel (en supposant que l'assembly du type est chargé - ce qui dans mon cas sera vrai), et de rechercher dans tous les assemblys et leurs types pour les noms correspondants (Type.FullName). Comme le domaine de l'application comporte plus de 80 assemblys chargés avec des milliers de types définis, cela peut entraîner un certain retard dans l'interface utilisateur (je le fais dans un IValueConverter). Pour pallier cela, j'utilise une liste de jetons de clé publique d'assembly bien connus pour éliminer tous les assemblages que je sais qui seront chargés et qui ne contiendront pas les types que je recherche. Cette solution est modérément réussie.

Ma question est, existe-t-il des moyens plus rapides et meilleurs que je peux utiliser pour trouver un type dans l'AppDomain actuel qui correspond à une chaîne contenant son nom complet?

Voici mon code actuel:

private static string[] wellKnownTokens = new string[] { 
    "b03f5f7f11d50a3a", 
    "4fe470e63e2d354f", 
    "b77a5c561934e089", 
    "31bf3856ad364e35" }; 

private Type GetTypeFromFullName(string fullName) 
{  
    var assys = from x in AppDomain.CurrentDomain.GetAssemblies() 
       where !wellKnownTokens.Any(y => x.FullName.EndsWith(y)) 
       select x; 

    return (from x in assys.SelectMany(x => x.GetTypes()) 
       where x.FullName == typeName 
       select x).FirstOrDefault(); 
} 

Répondre

1

Une approche consisterait à parcourir chaque assemblage chargé (vos 80 assemblages), et pour chacun d'eux ajouter le nom de l'assemblage au nom du type (c.-à-d. Rendre l'assemblage du nom de type qualifié) puis utilisez Type.GetType(string, boolean) [assurez-vous que le booléen throwOnError est false]

Sans regarder la mise en œuvre de Type.GetType(string, boolean), je ne sais pas si cela finirait par être plus rapide que boucle à travers tous les types dans toutes les assemblées ou non.

+0

En supprimant les assemblages, puis en utilisant cette méthode, permettez-moi de réduire le nombre d'itérations que mon algorithme devait accomplir de façon significative. Merci. – Will

0

Peut-être un algorithme de cache la création d'un temps fera le travail. Mappez une fois, utilisez indéfiniment :-)

+0

Malheureusement, cela ne fonctionnera pas pour moi, car de nouvelles classes et assemblages peuvent être ajoutés à l'appdomain à tout moment. – Will

Questions connexes