Accedere agli attributi personalizzati

Dopo che gli attributi sono stati associati a elementi del programma, è possibile verificarne l'esistenza ed esaminarne i valori tramite reflection. .NET fornisce , MetadataLoadContextche è possibile usare per esaminare il codice che non può essere caricato per l'esecuzione.

MetadataLoadContext

Il codice caricato nel MetadataLoadContext contesto non può essere eseguito. Non è pertanto possibile creare istanze di attributi personalizzati, operazione per cui è richiesta l'esecuzione dei costruttori. Per caricare ed esaminare gli attributi personalizzati nel MetadataLoadContext contesto, usare la CustomAttributeData classe . È possibile ottenere istanze di questa classe usando l'overload appropriato del metodo CustomAttributeData.GetCustomAttributes statico. Per altre informazioni, vedere Procedura: Esaminare il contenuto dell'assembly usando MetadataLoadContext.

Contesto di esecuzione

I principali metodi di reflection per l'esecuzione di query sugli attributi nel contesto di esecuzione sono MemberInfo.GetCustomAttributes e Attribute.GetCustomAttributes.

L'accessibilità di un attributo personalizzato viene verificata in relazione all'assembly in cui è collegato. In altri termini, si verifica se un metodo di un tipo dell'assembly a cui è collegato l'attributo personalizzato può chiamare il costruttore dell'attributo personalizzato.

I metodi come Assembly.GetCustomAttributes(Boolean) consentono di controllare la visibilità e l'accessibilità dell'argomento di tipo. Solo il codice nell'assembly che contiene il tipo definito dall'utente può recuperare un attributo personalizzato di quel tipo usando GetCustomAttributes.

Nell'esempio in C# riportato di seguito viene rappresentato un tipico modello di progettazione di attributi personalizzati. Viene illustrato il modello di reflection degli attributi personalizzati adottato dal runtime.

System.DLL
public class DescriptionAttribute : Attribute
{
}

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

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

Se il runtime tenta di recuperare gli attributi personalizzati per il tipo di DescriptionAttribute attributo personalizzato pubblico collegato al GetLanguage metodo, esegue le azioni seguenti:

  1. Il runtime verifica che l'argomento DescriptionAttribute di tipo a Type.GetCustomAttributes(Type type) sia pubblico e pertanto sia visibile e accessibile.
  2. Il runtime verifica che il tipo MyDescriptionAttribute definito dall'utente derivato da DescriptionAttribute sia visibile e accessibile all'interno dell'assembly System.Web.dll, in cui è collegato al metodo GetLanguage().
  3. Il runtime verifica che il costruttore di MyDescriptionAttribute sia visibile e accessibile all'interno dell'assembly System.Web.dll.
  4. Il runtime chiama il costruttore di con i parametri dell'attributo MyDescriptionAttribute personalizzato e restituisce il nuovo oggetto al chiamante.

Il modello di reflection degli attributi personalizzati può perdere istanze di tipi definiti dall'utente all'esterno dell'assembly in cui il tipo è definito. Ciò non è diverso dai membri della libreria di sistema di runtime che restituiscono istanze di tipi definiti dall'utente, ad esempio Type.GetMethods la restituzione di una matrice di RuntimeMethodInfo oggetti. Per impedire a un client di rilevare informazioni su un attributo personalizzato definito dall'utente, definire i membri del tipo come non pubblici.

Nell'esempio seguente viene illustrato il metodo principale per accedere agli attributi personalizzati tramite reflection.

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();
}
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);
        }
    }
}
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

Vedi anche