La réponse courte est, non, il n'y a aucun moyen de faire ce que vous demandez.
La réponse la plus longue est la suivante : Il existe une méthode spéciale de chargement des assemblages, Assembly.ReflectionOnlyLoad()
qui utilise un contexte de chargement "reflection-only". Cela vous permet de charger des assemblages qui ne peuvent pas être exécutés, mais dont les métadonnées peuvent être lues.
Dans votre cas (et, apparemment, dans tous les cas d'utilisation que je pourrais moi-même imaginer), ce n'est pas vraiment utile. Vous ne pouvez pas obtenir d'attributs typés à partir de ce type d'assemblage, seulement CustomAttributeData
. Cette classe ne permet pas de filtrer un attribut spécifique (le mieux que j'ai pu trouver est de le transformer en chaîne de caractères et d'utiliser la fonction StartsWith("[System.Diagnostics.Debuggable");
Pire encore, un chargement en réflexion seule ne charge aucun assemblage de dépendance, mais cela vous oblige à le faire manuellement . Cela est objectivement pire que ce que vous faites maintenant ; au moins, le chargement des dépendances est automatique.
(De plus, ma réponse précédente faisait référence au MEF ; je me suis trompé, il semble que le MEF inclut toute une tonne de code de réflexion personnalisé pour que cela fonctionne).
En définitive, vous ne pouvez pas décharger un assemblage une fois qu'il a été chargé. Vous devez décharger le tout le domaine des applications comme décrit dans cet article de MSDN.
UPDATE :
Comme indiqué dans les commentaires, j'ai pu obtenir les informations sur les attributs dont vous aviez besoin par le biais du chargement par réflexion uniquement (et d'un chargement normal), mais l'absence de métadonnées d'attributs typés rend la tâche très difficile.
S'il est chargé dans un contexte d'assemblage normal, vous pouvez obtenir les informations dont vous avez besoin assez facilement :
var d = a.GetCustomAttributes(typeof(DebuggableAttribute), false) as DebuggableAttribute;
var tracking = d.IsJITTrackingEnabled;
var optimized = !d.IsJITOptimizerDisabled;
S'il est chargé dans un contexte de réflexion uniquement, vous devez faire un peu de travail ; vous devez déterminer la forme que le constructeur d'attributs a prise, savoir quelles sont les valeurs par défaut et combiner ces informations pour obtenir les valeurs finales de chaque propriété. Vous obtenez les informations dont vous avez besoin comme ceci :
var d2 = a.GetCustomAttributesData()
.SingleOrDefault(x => x.ToString()
.StartsWith("[System.Diagnostics.DebuggableAttribute"));
A partir de là, vous devez vérifier le ConstructorArguments
pour voir quel constructeur a été appelé : celui-ci avec un seul argument ou celui-ci avec deux arguments. Vous pouvez alors utiliser les valeurs des paramètres appropriés pour déterminer les valeurs qu'auraient prises les deux propriétés qui vous intéressent :
if (d2.ConstructorArguments.Count == 1)
{
var mode = d2.ConstructorArguments[0].Value as DebuggableAttribute.DebuggingModes;
// Parse the modes enumeration and figure out the values.
}
else
{
var tracking = (bool)d2.ConstructorArguments[0].Value;
var optimized = !((bool)d2.ConstructorArguments[1].Value);
}
Enfin, vous devez vérifier si NamedArguments
qui pourraient remplacer celles définies sur le constructeur, en utilisant par exemple :
var arg = NamedArguments.SingleOrDefault(x => x.MemberInfo.Name.Equals("IsJITOptimizerDisabled"));
var optimized = (arg == null || !((bool)arg.TypedValue.Value));
Enfin, si vous exécutez ce programme sous .NET 2.0 ou plus, et que vous ne l'avez pas encore vu, MSDN le signale dans la page d'accueil du site. DebuggingModes
documentation :
Dans la version 2.0 de .NET Framework, les informations de suivi JIT sont toujours générées, et cet indicateur a le même effet que Default, à l'exception de la propriété IsJITTrackingEnabled qui est fausse, ce qui n'a aucune signification dans la version 2.0.