49 votes

C # Assembly.Load vs Assembly.ReflectionOnlyLoad

Je suis en train d'essayer de comprendre les différences entre l'Assemblage.De la charge et de l'Assemblée.ReflectionOnlyLoad.

Dans le code ci-dessous j'essaie de trouver tous les objets dans une assemblée qui hérite d'une interface donnée:

var myTypes = new List<Type>();

var assembly = Assembly.Load("MyProject.Components");

foreach (var type in assembly.GetTypes())
{
   if (type.GetInterfaces().Contains(typeof(ISuperInterface)))
   {
      myTypes.Add(type);
   }
}

Ce code fonctionne très bien pour moi, mais je faisais des recherches sur d'autres éventuellement de meilleures solutions de rechange et est venu à travers l'Assemblée.ReflectionOnlyLoad() la méthode.

Je suppose que depuis que je ne suis pas du chargement ou de l'exécution de l'un quelconque des objets, essentiellement à l'interrogation sur leurs définitions que j'ai pu utiliser ReflectionOnlyLoad une légère augmentation de la performance...

Mais il s'avère que lorsque je change l'Assemblée.Charge à l'Assemblée.ReflectionOnlyLoad j'obtiens l'erreur suivante lors de l'appel de l'assemblée.GetTypes():

Système.De la réflexion.ReflectionTypeLoadException: Impossible de charger un ou plusieurs de la types requis. Récupérer le LoaderExceptions de la propriété pour plus d' de l'information.

Je suppose que le code ci-dessus ne faisais la réflexion et à "regarder" la bibliothèque... mais est-ce une sorte d'instance du Principe d'Incertitude de Heisenberg en vertu de laquelle la recherche à la bibliothèque et les objets, il est effectivement tentant de les instancier une certaine façon?

Merci, Max

28voto

Kent Boogaart Points 97432

Comme par Jon répondre, il serait utile de savoir ce qu' LoaderExceptions. En lieu et place de cette information, je pense que je peux hasarder une conjecture. À partir de MSDN:

Si l'assemblée a des dépendances, le ReflectionOnlyLoad méthode ne permet pas de les charger. Si vous avez besoin d'examiner eux, vous devez vous charger vous-même.

Vous devez attacher un gestionnaire d'événements à AppDomain.ReflectionOnlyAssemblyResolve pour aider le CLR charger les dépendances de l'assemblée, vous êtes en train de charger. Avez-vous fait cela?

11voto

x0n Points 26002

Le ReflectionOnly méthodes sont la seule façon vous pouvez charger un Montage spécifique sur le disque pour examiner, sans passer par la Charge normale/LoadFrom règles. Par exemple, vous pouvez charger un disque de montage avec la même identité que celle dans le GAC. Si vous avez essayé cela avec LoadFrom ou LoadFile, le GAC assemblée est TOUJOURS chargé.

En outre, vous ne pouvez pas appeler GetCustomAttributes(...) sur le retour de l'Assemblée exemple, puisqu'il va tenter de les instancier les Attributs de l'assemblée, qui sont ReflectionOnly. Vous devez utiliser CustomAttributeData de la classe statique des méthodes pour cela.

Pas de types dans une assemblée chargée via ReflectionOnly peut être instancié.

10voto

C. Dragon 76 Points 5066

Je crois que votre général comprendre les différences entre la Charge et ReflectionOnlyLoad est correct. Le problème ici (je pense) c'est que même à charger un type, le CLR a besoin de lire les métadonnées à partir de l'assemblée le type lui-même est défini en tant que bien charger les métadonnées de chaque assemblée le type ancêtres sont définis dans. Donc, vous devez appeler l'Assemblée.ReflectionOnlyLoad toutes les assemblées qui définissent les types qui sont les ancêtres des types que vous êtes en train de charger.

Pour donner un exemple, supposons que vous disposez des éléments suivants de la classe définies en assemblée A.dll.

public class MyBase
{
   public void Foo() { }
}

et suivants de la classe définies en assemblée B.dll.

public class MySubclass : MyBase
{
}

Lorsque vous appelez de l'Assemblée.GetTypes de l'assemblée B.dll, le CLR essayez de charger le type MySubclass et de tous ses membres. Parce que la méthode Foo est défini dans MyBase en assemblée A.dll (et n'existe nulle part dans les métadonnées de B.dll), le CLR jeter le type de chargement des exceptions si l'assemblée A.dll n'a pas été chargé.

3voto

abatishchev Points 42425

Aucune méthode ne peut être exécutée à partir de l’assemblage, chargée avec ReflectionOnlyLoad() , vous obtiendrez InvalidOperationException . Il s'agit donc d'un moyen sûr de déterminer le contenu de l'assemblage à l'aide de la réflexion.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X