Dynamic columns via DynamicObject

This might be obvious to some of you, but I thought of writing a small post, since it has a nice example of the usage of .NET 4. DynamicObject.
Recently I had a requirement where I had to dynamically generate a tabular data (rows/cols) and use that data for Json serialization.
There are few ways of implementing this. The below example uses the .NET 4. DynamicObject to generate custom columns. I found this is quite easier and cleaner to implement than the tradition reflection based approach.

static Table GenerateData()
           {

               var columnsSet1 = new List<Col>() {new Col("row1Col1"), new Col("row1Col2"), new Col("row1Col3")};
               var columnsSet2 = new List<Col>() {new Col("row2Col1"), new Col("row2Col2"), new Col("row2Col3")};             

               var rows = new List<Row> {  new Row() { Cols = columnsSet1 },
                                           new Row() { Cols = columnsSet2 },

                                    };

               var rowList = new List<dynamic>();

               foreach (var row in rows)
               {
                   dynamic dynamicCol = new ColExpando(); //ColExpando derived from DynamicObject
                   var cols = row.Cols;

                   foreach (var col in cols)
                   {
                       dynamicCol.Column = col.Val;
                   }
                   rowList.Add(dynamicCol);
               }
               var tb = new Table { Data = rowList };
               return tb;
           }

        public class ColExpando: DynamicObject
        {
            private readonly Dictionary<string, object> members = new Dictionary<string, object>();
            private int colAppendIndex = 0;           

            public override bool TrySetMember(SetMemberBinder binder, object value)
            {

                   colAppendIndex++;
                    string key = binder.Name + colAppendIndex;

                    if (!members.ContainsKey(key))
                    {
                        members.Add(key, value);
                    }
                    else
                    {
                        members[key] = value;
                    }
                    return true;
              }

            public override bool TryGetMember(GetMemberBinder binder, out object result)
            {
                    if (members.ContainsKey(binder.Name))
                    {
                        result = members[binder.Name];
                        return true;
                    }

                    return base.TryGetMember(binder, out result);
              }

            public override IEnumerable<string> GetDynamicMemberNames()
            {
                return members.Keys;
            }
        }

Note that colAppendIndex is an incremental number which appends a number in front of the key of the property name. This gives us the uniqueness of the keys in the dictionary.
If you call this method in console app and binds to json as below


static void Main(string[] args)
           {
               var json = JsonConvert.SerializeObject(GenerateData(), Formatting.Indented); //using Newtonsoft.Json lib
               Console.WriteLine(json);
               Console.Read();
           }

Output:

{

  "Data": [

    {

      "Column1": "row1Col1",

      "Column2": "row1Col2",

      "Column3": "row1Col3"

    },

    {

      "Column1": "row2Col1",

      "Column2": "row2Col2",

      "Column3": "row2Col3"

    }

  ]

}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s