Verwendung der Attribute bei C (Teil 2)
Kommentare

Erstellung und Verwendung eigener Attribute
Im Folgenden wird gezeigt, wie mithilfe von Attributen ein eigener (Mini-) O/R Mapper realisiert werden kann. Dazu werden zunächst zwei Attributklassen implementiert.

Erstellung und Verwendung eigener Attribute

Im Folgenden wird gezeigt, wie mithilfe von Attributen ein eigener (Mini-) O/R Mapper realisiert werden kann. Dazu werden zunächst zwei Attributklassen implementiert. Die erste Attributklasse ist in Listing 2 zu sehen. Das neue Attribut namens TableAttribute dient dazu, einer (Entitäts-)Klasse den zugehörigen Tabellennamen zuzuordnen. Das Attribut wurde auf die Verwendung von Klassen beschränkt und darf nur einmal angewendet werden. Das zweite neue Attribut (Listing 3) definiert die neue Attributklasse ColumnAttribute. Über dieses Attribut, das mehrmals, aber nur auf Eigenschaften angewendet werden darf, können (Entitäts-)Eigenschaften mit Spaltennamen verknüpft werden. Durch die Verwendung der beiden Attribute ist es nun möglich, genügend Metainformationen zu hinterlegen, um daraus alle typischen CRUD-Datenbankoperationen automatisch generieren zu können. Die konkrete Verwendung der beiden neuen Attribute ist in Listung 4 abgebildet. Dort wird auch deutlich, dass bei der Verwendung des Attributs das Suffix Attribute entfallen kann.

Listing 2

[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class TableAttribute : Attribute
{
  private string tableName = string.Empty;
  public TableAttribute (string tableName)
  {
    this.tableName = tableName;
  }
}  

Listing 3

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class ColumnAttribute : Attribute
{
  private string columnName = string.Empty;
  public ColumnAttribute(string columnName)
  {
    this.columnName = columnName;
  }
}  

Listing 4: Verwendung

[Table("Personen")]
public class Employee
{
  [Column("Vorname")]
  public string FirstName { get; set; }
  [Column("Nachname")]
  public string LastName { get; set; }
  [Column("Beschaeftigt")]
  public DateTime HireDate { get; set; }
}  

Auslesen der Metainformationen

Die Verwendung von Attributen ist natürlich nur dann sinnvoll, wenn die hinterlegten Informationen auch weiterverarbeitet werden. Im oberen Beispiel wurden zwei neue Attributklassen angelegt, um Informationen über die Herkunft der Daten zu hinterlegen. Aus diesen Informationen kann zur Laufzeit automatisch ein SQL-Befehl generiert werden. Dazu müssen die eingebetteten Informationen ausgelesen werden, was per Reflection einfach möglich ist. Listing 5 demonstriert dazu die notwendige Vorgehensweise. Zunächst wird der auszulesende Datentyp in die Variable targetType geschrieben. Danach ermöglicht die Methode GetCustomAttributes das Auslesen von Attributen. Dabei ist der Methode lediglich der gewünschte Attributtyp zu übergeben. Danach liefert die Methode ein Array gefundener Attribute zurück. Anschließend werden die hinterlegten Attribute der Eigenschaften abgerufen. Dazu werden zunächst alle definierten Eigenschaften abgerufen (PropertyInfo Array) und mittels foreach-Schleife durchlaufen. Bei jedem Schleifendurchlauf ermöglicht die Methode GetCustomAttribute wiederum den Zugriff auf die eigenen Attribute. Nachdem alle Informationen ausgelesen wurden, ist es möglich, benötigte SQL-Kommandos generisch zu erstellen.

Listing 5

public static void ReadAttributes(Employee employee)
{
  Type targetType = typeof(Employee);    
  object[] attrTable = targetType.
                           GetCustomAttributes(typeof(TableAttribute), false);
  Console.WriteLine("Table: {0}", (attrTable[0] as TableAttribute).TableName);
  PropertyInfo[] props = typeof(Employee).GetProperties();
  ColumnAttribute attrCol = null;
  object[] customAttributes = null;
  foreach (PropertyInfo prop in props)
  {
    customAttributes = prop.GetCustomAttributes(typeof(ColumnAttribute), false);
    if (customAttributes != null && customAttributes[0] != null)
    {
      attrCol = (customAttributes[0] as ColumnAttribute);
      Console.WriteLine("Column: {0}", attrCol.ColumnName);
    }
  }
}  

Zusammenfassung

Mithilfe von Attributen können zusätzliche Informationen zu Programmeinheiten deklarativ hinterlegt werden. Die Spannweite der Möglichkeiten von Attributen ist dabei sehr groß. Viele Attribute fügen lediglich zusätzliche Informationen und Beschreibungen hinzu, die durch andere Prozesse weiterverarbeitet werden. Andere Attribute wie Serializable erweitern hingegen Klassen um zusätzliche Funktionen. Auch das Laufzeitverhalten kann über Attribute, wie es das Attribut ConditionalAttribute zeigte, beeinflusst werden. Schließlich existieren noch Attribute, die während der Übersetzungszeit durch den Compiler ausgewertet werden. Das Einsatzfeld von Attributen ist quasi unbegrenzt und kann durch eigene noch erweitert werden.

Marc André Zhou ist als freiberuflicher .NET-Technologieberater tätig. Seine Schwerpunkte liegen im Bereich .NET-Entwicklung, SharePoint, Softwarearchitekturen und Frameworks. Sie erreichen ihn unter zhou@dev-sky.net.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -