Sunday, March 31, 2013

Dynamic property or Extended property in C#

I was busy to create architecture of (C#) project. In the time of development, I faced a situation where it will be good to have a dynamic property generation. I did some search, and found many examples. But after going through all, I found something, which is really nice and solve my problem. My problems are-
1>  I need to get all the data fetched from table in DB in a custom and pre-defined model in c#, but sometime DB queries can return some columns which are not in the defined properties of predefined model.
2>  When I do serialization of the model in c#, it should serialize in normal and proper way, with or without extra columns returned from DB.
Suppose, I define a model –
Public class EmpModel{
Public string EmpName{get; set;}
Public string EmpId{get; set;}
And I also write three SQL queries-
SELECT EmpName,EmpId,EmpAddress from tbl_Employee
SELECT EmpName,EmpId,EmpDept from tbl_Employee
SELECT EmpName,EmpId,EmpDOB from tbl_Employee
Now, as you can see, the queries are returning three columns, but the model only has two properties. I cannot manage EmpAddress, EmpDept and EmpDOB in model. As well as, the 3rd field will be different in type also. To manage this situation, I found-
1>     AssemblyBuilder
2>     ModuleBuilder
3>     TypeBuilder
4>     FieldBuilder
5>     PropertyBuilder
6>     MethodAttributes
7>     MethodBuilder

These are the main building blocks of my solution.

The theory of the solution is, I have to create a class which will have EmpModel as a base class and with the properties (Extra properties) needed. All these, need to be done dynamically.

For all these, I managed to write two method sets(Three methods), which will handle everything for me-
MethodSet 1 (to bind DB columns with Model properties)-[Contains two methods]
public void getModelFromObject<T, T1>(object valu, ref List<T> el,Dictionary<string,Type> props) where T1 : T, new()
            DataTable dt = ((DataSet)valu).Tables[0];
            Type dynamicType = getType(typeof(T).Name+ "Ext", props, typeof(T1));
            foreach (DataRow dr in ((DataSet)valu).Tables[0].Rows)
                T item = (T)Activator.CreateInstance(dynamicType);
                getObject<T>(dr, ref item, dt);
                T tsts = item;



public void getObject<T>(DataRow dr,ref T obj, DataTable dt)
            foreach (DataColumn dc in dt.Columns)
                if (obj.GetType().GetProperty(dc.ColumnName) != null)
                        obj.GetType().GetProperty(dc.ColumnName).SetValue(obj, dr[dc.ColumnName], null);

MethodSet 2(to create extended properties)-[Contains one method]
  public Type getType(string dynamicClassName, Dictionary<string, Type> propertyList, Type baseClassType)
            bool isNewProperties = false;

            AssemblyBuilder assemblyBilder = System.Threading.Thread.GetDomain().DefineDynamicAssembly
            (new AssemblyName(dynamicClassName + "Assembly"), AssemblyBuilderAccess.Run);
            ModuleBuilder moduleBilder = assemblyBilder.DefineDynamicModule(dynamicClassName + "Module");

            TypeBuilder typeBilder = moduleBilder.DefineType(dynamicClassName, TypeAttributes.Public | TypeAttributes.Class, baseClassType);

            string propertyName = null;
            Type propertyType = null;
            var baseClassObj = Activator.CreateInstance(baseClassType);
            foreach (var prop in propertyList)
                propertyName = prop.Key;
                propertyType = prop.Value;

                var propExist = baseClassObj.GetType().GetProperty(propertyName);
                if (propExist != null)

                FieldBuilder filedBilder = typeBilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);

                PropertyBuilder propertyBilder = typeBilder.DefineProperty(propertyName, System.Reflection.PropertyAttributes.None, propertyType,
                            new Type[] { propertyType });
                MethodAttributes GetSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig;

                MethodBuilder currGetPropMthdBilder = typeBilder.DefineMethod("geter", GetSetAttr, propertyType, null);

                ILGenerator currtGetIL = currGetPropMthdBilder.GetILGenerator();
                currtGetIL.Emit(OpCodes.Ldfld, filedBilder);

                MethodBuilder currSetPropMthdBilder = typeBilder.DefineMethod("seter", GetSetAttr, null, new Type[] { propertyType });

                ILGenerator currSetIL = currSetPropMthdBilder.GetILGenerator();
                currSetIL.Emit(OpCodes.Stfld, filedBilder);

                isNewProperties = true;

            if (isNewProperties == false)
                return baseClassType;
            return typeBilder.CreateType();
And now, the use of these methods-
     List<IEmp> obj = new List<IEmp>();

            Dictionary<string, Type> props= new Dictionary<string, Type>();
            props.Add("EmpAddress", typeof(string));//if more then one add more.
            modelPlatform.init().getModelFromObject<IEmp,Emp>(ds, ref obj, val);//ds- is the dataset returned from DB
            return obj;

Same for two other queries also.
That’s it, Enjoy.

No comments: