Accès aux attributs personnalisés

Une fois les attributs associés aux éléments du programme, il est possible d'utiliser la réflexion pour exécuter des requêtes visant à déterminer leur existence et leurs valeurs. Dans la version 1.0 et 1.1 du .NET Framework, les attributs personnalisés sont examinés dans le contexte d'exécution. Le .NET Framework version 2.0 fournit un nouveau contexte de chargement, le contexte de réflexion uniquement, lequel permet d'examiner du code qui ne peut pas être chargé pour exécution.

Contexte de réflexion uniquement

Le code chargé dans le contexte de réflexion uniquement ne peut pas être exécuté. Cela signifie qu'il est impossible de créer des instances d'attributs personnalisés car cela nécessiterait l'exécution de leurs constructeurs. Pour charger et examiner des attributs personnalisés dans le contexte de réflexion uniquement, utilisez la classe CustomAttributeData. Vous pouvez obtenir des instances de cette classe en utilisant la surcharge appropriée de la méthode statique CustomAttributeData.GetCustomAttributes. Consultez Comment : charger des assemblys dans le contexte de réflexion uniquement.

Contexte d'exécution

Les principales méthodes de réflexion utilisées pour l'exécution de requêtes se rapportant aux attributs dans le contexte d'exécution figurent dans MemberInfo.GetCustomAttributes et Attribute.GetCustomAttributes.

L'accessibilité d'un attribut personnalisé est vérifiée par rapport à l'assembly auquel il est attaché. Cela équivaut à vérifier si une méthode d'un type de l'assembly auquel est attaché l'attribut personnalisé peut appeler le constructeur de cet attribut.

Les méthodes telles que Assembly.GetCustomAttributes(Boolean) vérifient la visibilité et l'accessibilité de l'argument de type. Seul le code de l'assembly qui contient le type défini par l'utilisateur peut récupérer un attribut personnalisé de ce type à l'aide de GetCustomAttributes.

L'exemple C# suivant est un modèle de design d'attributs personnalisés courant. Il illustre le modèle de réflexion d'attribut personnalisé du runtime.

System.DLL
public class DescriptionAttribute : Attribute
{
}

System.Web.DLL
internal class MyDescriptionAttribute : DescriptionAttribute
{
}

public class LocalizationExtenderProvider
{
    [MyDescriptionAttribute(...)]
    public CultureInfo GetLanguage(...)
    {
    }
}

Si le runtime tente de récupérer les attributs personnalisés du type d'attribut personnalisé public DescriptionAttribute attaché à la méthode GetLanguage, il effectue les actions suivantes :

  1. Vérifier que l'argument de type DescriptionAttribute pour Type.GetCustomAttributes(Type type) est public, et qu'il est, par conséquent, visible et accessible.

  2. Vérifier que le type défini par l'utilisateur MyDescriptionAttribute, dérivé de DescriptionAttribute, est visible et accessible dans l'assembly System.Web.DLL, où il est attaché à la méthode GetLanguage().

  3. Vérifier que le constructeur de MyDescriptionAttribute est visible et accessible dans l'assembly System.Web.DLL.

  4. Appeler le constructeur de MyDescriptionAttribute à l'aide des paramètres d'attribut personnalisé et retourner le nouvel objet à l'appelant.

Le modèle de réflexion d'attribut personnalisé peut diffuser des instances de types définis par l'utilisateur hors de l'assembly dans lequel le type est défini. Cela n'est guère différent des membres de la bibliothèque système du runtime qui retournent des instances de types définis par l'utilisateur, par exemple Type.GetMethods() qui retourne un tableau d'objets RuntimeMethodInfo. Pour empêcher un client de découvrir des informations se rapportant à un type d'attribut personnalisé défini par l'utilisateur, faites des membres du type des membres non publics.

L'exemple suivant montre la procédure de base pour utiliser la réflexion et accéder aux attributs personnalisés.

Imports System

Public Class ExampleAttribute
    Inherits Attribute

    Private stringVal As String

    Public Sub New()
        stringVal = "This is the default string."
    End Sub

    Public Property StringValue() As String
        Get
            Return stringVal
        End Get
        Set(Value As String)
            stringVal = Value
        End Set
    End Property
End Class

<Example(StringValue := "This is a string.")> _
Class Class1
    Public Shared Sub Main()
    Dim info As System.Reflection.MemberInfo = GetType(Class1)
        For Each attrib As Object In info.GetCustomAttributes(true)
            Console.WriteLine(attrib)
        Next attrib
    End Sub
End Class
using System;

public class ExampleAttribute : Attribute
{
    private string stringVal;

    public ExampleAttribute()
    {
        stringVal = "This is the default string.";
    }

    public string StringValue
    {
        get { return stringVal; }
        set { stringVal = value; }
    }
}

[Example(StringValue="This is a string.")]
class Class1
{
    public static void Main()
    {
        System.Reflection.MemberInfo info = typeof(Class1);
        foreach (object attrib in info.GetCustomAttributes(true))
        {
            Console.WriteLine(attrib);
        }
    }
}
using namespace System;

public ref class ExampleAttribute : Attribute
{
private:
    String^ stringVal;

public:
    ExampleAttribute()
    {
        stringVal = "This is the default string.";
    }


    property String^ StringValue
    {
        String^ get() { return stringVal; }
        void set(String^ value) { stringVal = value; }
    }
};

[Example(StringValue="This is a string.")]
public ref class Class1
{
public:
    static void Main()
    {
        System::Reflection::MemberInfo^ info = Type::GetType("Class1");
        for each (Object^ attrib in info->GetCustomAttributes(true))
        {
            Console::WriteLine(attrib);
        }
    }
};

int main()
{
    Class1::Main();
}

Voir aussi

Référence

MemberInfo.GetCustomAttributes

Attribute.GetCustomAttributes

Concepts

Affichage des informations de type

Considérations sur la sécurité de la réflexion