Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Take Control of .NET Using Custom Attributes : Page 2

Don't content yourself with the attributes that are built in to .NET. Write custom attributes to add your own meta-data to properties, methods, classes, and other program elements, giving you fine-grain control.


advertisement
Reading Custom Attributes at Runtime
To read the value of a custom attribute, call the GetCustomAttributes function of the MemberInfo class. (The MemberInfo class is inherited by EventInfo, FieldInfo, MethodBase, PropertyInfo, and System.Type, and is therefore available from most of the reflection objects).

The GetCustomAttributes function returns an array of Attribute objects. You should always check to make sure that at least one item is in the returned array. It is possible to define the same attribute multiple times on an element, and not all elements will have the attribute defined that you are searching for, so GetCustomAttributes can return an array with multiple results, or an empty array.

This code displays the assembly title of the executing assembly by reading the assembly's AssemblyTitle attribute value.



Dim objAttrSet() As System.Reflection.AssemblyTitleAttribute objAttrSet = _ Reflection.Assembly.GetExecutingAssembly.GetCustomAttributes( _ GetType(System.Reflection.AssemblyTitleAttribute), False) If objAttrSet.Length = 0 Then MsgBox("No Assembly Title attribute was found!") Else MsgBox(objAttrSet(0).Title) End If

This example reads a custom attribute of a class.

Dim objAttrSet() As System.Diagnostics.MonitoringDescriptionAttribute objAttrSet = _ Me.GetType.GetCustomAttributes( _ GetType(System.Diagnostics.MonitoringDescriptionAttribute), False) If objAttrSet.Length = 0 Then MsgBox("No MonitoringDescription attribute was found!") Else MsgBox(objAttrSet(0).Title) End If

Implementation ideas—Automatic List View
The sample code for this article uses reflection and custom attributes to automatically populate a list view's column headers for a specified object type. The code contains:
  1. A form containing an instance of our derived list view and some sample code to populate it.
  2. Our custom attribute class, ListDisplayAttribute.
  3. Our derived listview class. This class adds two methods, SetType(), which populates the list view's column headers collection, and AddItem(), which adds a ListViewItem to the list view, automatically populating the subitems collection for that ListViewItem.
  4. A sample class for holding data called SampleContactObject. This class contains four properties: "name," "password," "email," and "telephone." This class contains examples of the use of the ListDisplay Attribute.

The ListDisplayAttribute class is pretty straightforward—it is derived from System.Attribute and contains three properties:

Display

true/false

Determines whether to display the property in a list view column

ColumnText

string

The text to place in the column header

DefaultWidth

integer

The width to assign to the column header

Our derived list view class has a GetProperties to get a PropertyInfo object that represents each property in the type.

Author's Note: The code example has been simplified. Download the full version of the code by clicking the "download the code" link in the left column.)

' Loop through all the properties in the object For Each prpObjectProperty In mtypListItemType.GetProperties ' Add column headers If prpObjectProperty.GetCustomAttributes( _ GetType(Devx.ListDisplayAttribute), True).Length = 0 Then ' Set default properties Else ' Attribute found attListAttribute = prpObjectProperty.GetCustomAttributes( _ GetType(Devx.ListDisplayAttribute), True)(0) ' read values blnShowColumn = attListAttribute.Display intWidth = attListAttribute.DefaultWidth ' The header text is not always specified, so we need ' to use the property name if it is left blank. strHeader = attListAttribute.ColumnText If strHeader.Length = 0 Then strHeader = prpObjectProperty.Name End If End If Next

Inside the loop, I call GetCustomAttributes, check that it returns at least one result, and then read the Display, DefaultWidth, and ColumnText properties into variables used elsewhere in the code.

You can create generic code that uses "self-describing" program elements using reflection and custom attributes. I've used this technique to create generic classes that read and write themselves to database tables and am experimenting with self-documenting code, just to give a couple of examples. There are many uses for this technique, limited only by your requirements and imagination.



Anthony Glenwright is Product Development Manager at Inventua. Inventua creates tools to manage the workflows of running a successful software organization and general-purpose tools designed to improve software quality. You can contact him via the Website at or directly by email at anthony.glenwright@inventua.com.
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date