December 1, 2006

Reflection And Custom Attributes

Reasonable explanation of reflection Defining a custom class attribute
[AttributeUsage(AttributeTargets.Class)] // attribute is for classes only
public class CustomClassAttribute : System.Attribute
{
    private string m_Caption;
    public CustomClassAttribute(string caption)
    {
       m_Caption = caption;
    }

    public string Caption
    {
       get { return m_Caption; }
    }
}
Processing the Assembly to get the attributes
public void Discover()
{
    Type[] types = System.Reflection.
Assembly.GetExecutingAssembly().GetTypes();
    foreach (Type type in types) // Go over all the types
    {
      // Look for all types derived from BaseClass 
      if (type.BaseType == typeof(BaseClass)) 
      {
        // Look for the 'CustomClassAttribute' attributes on that type
        object[] attributes = 
type.GetCustomAttributes(typeof(CustomClassAttribute), false);
        if (attributes.Length > 0)
        {
          // iterate through the attributes, retrieving the 
          // properties
          foreach (Object attribute in attributes)
          {
            CustomClassAttribute fca = (CustomClassAttribute)attribute;
            DoSomething(type.FullName, fca.Caption);
            break;
          }
        }
      }
    }
}
The attribute is used like this
[CustomClass("Some caption")]
public class SomeClass : BaseClass 
{

...
}
For example, say you have some properties on a type that you wish to iterate through but you do not wish to get the Obsolete ones (marked using "[Obsolete]", then the code would be something like this:
Type type = typeof(MyXXXType);
PropertyInfo[] props = type.GetProperties();
foreach (PropertyInfo prop in props)
{
    object[] attributes = prop.GetCustomAttributes(typeof(ObsoleteAttribute), false);
    if (attributes.Length > 0) // If property is marked as Obsolete then ignore it
        continue;

    // otherwise do something with the property
}

No comments: