Attributes


C# Attributes.
Setting attributes on properties, classes, etc. Can help you write cleaner code, and simplify development. So learning about attributes is verry useful. To start with I will show you a peace of code that will help you understand the capability's of attributes.
[XmlRoot("DataType")] 
public class MyData {

  [XmlElement("DataName")]
  public string Name { get; set; }
}

In the above code I have specified that when serializing objects of type "MyData". Then the MyData type should be writen as "DataType" and the Name property should be writen as "DataName". So writing the object to xml would produce the folowing xml:

<DataType>
 <DataName>...</DataName>
</DataType>

Do you get the point? We attach attributes to classes properties etc, and then using what's called "Reflection" the system extracts thease attributes, and use it to process data based on thease.

So let's try making our own simple usefull attribute.
First we need to defigne a problem to solve: Create a simple way to generate SQL statements, making it easy to reprecent objects in a relational database. First let's create a simple object, and a table in the database that we can use for this example.

public class DataObject
{
  public int ID { get; set; }
  public string Name { get; set; }
  public string Description { get; set; }
}

And the data table that i want to store the object in looks like this:


Now there are lot's of approtches on how you can generate SQL statements that can move object of the DataObject type, to the database. But I will now outline how you could do it using attributes. Imagine that we had an attribute awaiable called "TableName" that you could attach to classes, this should tell what database table to put the objects into. And also imagine that we could specify a "FieldName" attribute on each property on the class. Then we have a way to map objects into a database.

[TableName("ObjectStore")]
public class DataObject
{
  [FieldName("autoId")]
  public int ID { get; set; }

  [FieldName("objectName")]
  public string Name { get; set; }

  [FieldName("dataText")]
  public string Description { get; set; }
}

So now it's time to write the attributes. And it's verry simple, you just have to write classes that inherits from the Attribute base class. Here's the code for the sample attribute classes.

[System.AttributeUsage(System.AttributeTargets.Class)]
public class TableName : System.Attribute
{
  private string name;
  public TableName(string name)
  {
    this.name = name;
  }

  public string Name { get { return name; } }
}

[System.AttributeUsage(System.AttributeTargets.Property)] public class FieldName : System.Attribute { private string name; public FieldName(string name) { this.name = name; } public string Name { get { return name; } } }

So to breafly walk through the custom attributes: First we declare the "System.AttributeUsage" attribute, that specify what the attribute can be used on. Where TableName can be set on Classes, and FieldName on properties. Then we create a class that inherits from System.Attribute, and both classs take a string "Name" as input parameter.

Using these attributes we can then write a method that transforms it into an SQL statement. Or eaven better, write an extention method that can extend all the classes. To doo it as an extention first make a simple interface and make the classes inherit from that interface.

public interface iMySQL { }

//Add interface to the classes
public class DataObject : iMySQL // Use this line instead on the "DataObject" class.
{
  ...
}

Now it's just a matter of writing extention methods that can transform the attributes into SQL statements. This is done by using the System.Attribute.GetCustomAttribute function that can extract attributes using reflection. Here is a simple demo extention method that writes an update statement... Be aware that it's just an example not a fully featured toolset!

public static class Extentions
{
  public static string CreateUpdateSQL(this iMySQL data)
  {
    Type T = data.GetType();
    TableName MyTable = (TableName)System.Attribute.GetCustomAttribute(T, typeof(TableName), false);
    string TableName = MyTable.Name;

    string UpdateString = "UPDATE " + TableName + " SET";
    foreach (PropertyInfo info in T.GetProperties()) {
      FieldName MyField = (FieldName)info.GetCustomAttribute(typeof(FieldName), true);
      string Value = info.GetValue(data).ToString();
      UpdateString += " " + MyField.Name + "='" + Value +"'";
    }
    return UpdateString;
  }
}

To briefly walk through the code. I first create a static class with an extention method (Read the Extention method guide). Then I get the instance type of data (eg.same as typeof(DataObject)). Now I get the table name by using GetCustomAttribute and only find the "TableName" attribute. Last but not least i run through all the Propertys of the object, and find ther value (info.GetValue) and build the SQL string (UpdateString).

Demo example:
DataObject Data = new DataObject() { ID = 0, Name = "Soren Kielsgaard Hansen", Description = "Spells.dk is a cool webpage." };
string SQLUpdate = Data.CreateUpdateSQL();
Console.WriteLine(SQLUpdate);
// Output of example
// UPDATE ObjectStore SET autoId='0' objectName='Soren Kielsgaard Hansen' dataText='Spells.dk is a cool webpage.'

Remember this was "just" a demo, so the aim was to show you how to do it, not walk through a finished polished code. And as you can see the above small demo is almost outputting a full SQL update statement, so with just a small bit of modifications it can be extended to a full "SQL object synchronization" package.

If you are on this page looking for a full package that you can use then i can tell you that I'm working on packaging the above into a development tool that will be awaiable HERE soon...

Hope it was helpfull :-)


Please. If you like the page donate something!
Anything eaven just 1$ that's fine :-)