In our current project we want to fill a grid control with data that is comming from value objects. I can hear you think: “Easy, just use standard .NET data binding!” True, but the grid control that we are currently using does not have full databinding support, and using another control is not an option at this moment.

Rather than implementing some logic that will map the contents of each value object type to a row in our grid control, I chose to create a utility class (named PropertyReflector) that allows us to read and write the properties of our value objects through reflection. Since we need to access properties of value-objects within other value-objects, the utility class must also be able to do deep reflection: getting and setting values of nested objects.

Read the rest of this article for examples and source code!

[03-Feb-2007] Update: uploaded a new version of the PropertyReflector source
[03-Feb-2007] Update: uploaded the nunit tests for PropertyReflector

To make this work, our value objects must meet the following requirements:

  • Declare public get/set property accessors for fields that should be displayed in/filled from the grid
  • Have a default constructor, so instances of nested objects can be created if necessary when setting properties on them

To demonstrate how the PropertyReflector utility class works, we’ll use the following test object:

public class TestObject
{
   private TestObject parent;
   private string name;
 
   public TestObject() {}
 
   public TestObject(string name)
   {
      this.name = name;
   }
 
   public TestObject(string name, TestObject parent)
   {
      this.parent = parent;
      this.name = name;
   }
 
   public TestObject Parent
   {
      get { return parent; }
      set { parent = value; }
   }
 
   public string Name
   {
      get { return name; }
      set { name = value; }
   }
}

As you can see, the TestObject has a name and a nested TestObject representing its parent. It has public property accessors for both fields, a default constructor and a constructor with parameters for ease of use.

We can now use the PropertyReflector utility class to get and set properties on our TestObject, like this:

TestObject to = new TestObject(
   "Son", 
   new TestObject(
      "Father", 
      new TestObject("Grandfather")
   )
);         
 
PropertyReflector pr = new PropertyReflector();                  
object grandFathersName = 
   pr.GetValue(to, "Parent.Parent.Name");
 
Console.Out.WriteLine("grandFathersName = {0}", 
   grandFathersName );
 
to = new TestObject("Son");
pr.SetValue(to, "Parent.Parent.Name", 
   "Another Grandfather");
 
object anotherGrandfathersName = 
   pr.GetValue(to, "Parent.Parent.Name");
 
Console.Out.WriteLine("(Son).Parent.Parent.Name = {0}", 
   anotherGrandfathersName);

You can see some nested TestObjects being created: Son > Father > Grandfather. In line 10, the Name property of the deepest TestObject is obtained. Notice that the property names are separated by dots to indicate a new level in the hierarchy: “Parent.Parent.Name”.

To demonstrate the ability of instantiating objects for nested properties that have null references, a new TestObject instance is created on line 16, after which the name of its grandfather is set (lines 17 & 18) without creating father or grandfather objects first.

Running the code above will generate the following output:

grandfathersName = Grandfather
(Son).Parent.Parent.Name = Another Grandfather

The use of the PropertyReflector class is not limited to value objects, you could use it to do deep reflection on any type of object that declares public properties. To demonstrate this, we’ll get the value for the Length property of a String object:

PropertyReflector pr = new PropertyReflector();         
string a = "1234";
object length = pr.GetValue(a, "Length");
Console.Out.WriteLine("length  = {0}", length);

The output for this code will be:

length  = 4

Although this is nothing exotic, using this utility class we have been able to describe our grid and its contents completely through xml. No extra coding is needed in our project to create a grid for a new business concept, we simply specify the layout settings and the name of the associated property for each column.

I also added caching of the PropertyInfo and ConstructorInfo instances to speed up the reflection process. All internal access to these caches has been made thread-safe.

Here is a link to the source code for the PropertyReflector class. I also have some NUnit tests for it that test how it behaves with inheritance and dynamic proxies generated at runtime.
Feel free to use and change it, but if you make improvements to it, I would appreciate it if you’d send them back to me :).