ExpandoObject – add properties dynamically

ExpandoObject class allows to create an object of dynamic type. This dynamic type object allows to attach properties to it at runtime.

While working on a project recently, I had to create a data service which builds response for a data request without knowing the schema and source of data.

The request contains following information

Request.TableName : “SegmentTable”

Request.RequiredFields: [“SegmentKey”, “SegmentIndex”, “Attribute1”, “Attribute2”, “Attribute4”]

SegmentTable looks like something

SegmentID

SegmentKey

SegmentIndex

Attribute1

Attribute2

Attribute3

Attribute4

…….

Data service builds a query like [SELECT * from {SegmentTable}] and then creates a collection of ExpandoObjects  against each row returned against this query.

This code snippet shows how an ExpandoObject is created from a datatable row.

 class ResponseBuilder
 {
    public dynamic BuildResponseRow(DataRow row, string[] requiredFields)
    {
      dynamic responseRow = new ExpandoObject();
      foreach (var field in requiredFields)
      {
        // Add a new propery to expando object and assign it a value.
        ((IDictionary<string, object>)responseRow).Add(field, row[field]);
      }

       return responseRow;
    }
 }

ExpandoObject uses dictionary underneath to achieve this but for the users its very seamless. We can attach the properties directly to the object as well. In this case since the names of those properties were also coming from database/request so we had to type cast in order to add those names dynamically.

There may be scenarios where we know the fields that we have to return, in this case we can directly assign the properties like

class ResponseBuilder
{
  public dynamic BuildResponseRow(DataRow row)
  {
    dynamic responseRow = new ExpandoObject();
    responseRow.Attribute1 = row["Attribute1"];
    responseRow.Attribute2 = row["Attribute2"];
    responseRow.Attribute4 = row["Attribute4"];
    return responseRow;
  }
}

Make sure you really need ExpandoObject before you use it. There might be scenarios where you can simply use a dictionary. In my scenario, I could use dictionary but this would lead me to a limitation in future (out of scope here) so I used Expando.

Leave a Reply