How to create own dynamic type or dynamic object in C#
using System.Reflection; using System.Reflection.Emit;
public static class MyTypeBuilder { public static System.Collections.IList CreateInstanceIList(Type _type) { Type customList = typeof(List<>).MakeGenericType(_type); var result = (System.Collections.IList)Activator.CreateInstance(customList); return result; } public static Type CompileResultType(Dictionary<string, Type> listOfFields) { TypeBuilder tb = GetTypeBuilder(); foreach (var field in listOfFields) CreateProperty(tb, field.Key, field.Value); Type objectType = tb.CreateType(); return objectType; } private static TypeBuilder GetTypeBuilder() { var typeSignature = "MyDynamicType_" + DateTime.Now.ToString("yyyyMMddHHmmss"); var an = new AssemblyName(typeSignature); AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule"); TypeBuilder tb = moduleBuilder.DefineType(typeSignature, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, null); return tb; } private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType) { FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private); PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null); MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes); ILGenerator getIl = getPropMthdBldr.GetILGenerator(); getIl.Emit(OpCodes.Ldarg_0); getIl.Emit(OpCodes.Ldfld, fieldBuilder); getIl.Emit(OpCodes.Ret); MethodBuilder setPropMthdBldr = tb.DefineMethod("set_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { propertyType }); ILGenerator setIl = setPropMthdBldr.GetILGenerator(); Label modifyProperty = setIl.DefineLabel(); Label exitSet = setIl.DefineLabel(); setIl.MarkLabel(modifyProperty); setIl.Emit(OpCodes.Ldarg_0); setIl.Emit(OpCodes.Ldarg_1); setIl.Emit(OpCodes.Stfld, fieldBuilder); setIl.Emit(OpCodes.Nop); setIl.MarkLabel(exitSet); setIl.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getPropMthdBldr); propertyBuilder.SetSetMethod(setPropMthdBldr); } }
How to use
public JsonResult DynamicObject() { Dictionary<string, Type> listOfFields = new Dictionary<string, Type>(); listOfFields.Add("Name", typeof(string)); listOfFields.Add("Age", typeof(int)); var myType = MyTypeBuilder.CompileResultType(listOfFields); var myObject = Activator.CreateInstance(myType); myType.GetProperty("Name").SetValue(myObject, "Tuan", null); myType.GetProperty("Age").SetValue(myObject, 20, null); object name = myType.GetProperty("Name").GetValue(myObject); return Json(name.ToString(), JsonRequestBehavior.AllowGet); // return Json(myObject, JsonRequestBehavior.AllowGet); }
Mapping data to List
public JsonResult DynamicObject2() { Dictionary<string, Type> listOfFields = new Dictionary<string, Type>(); listOfFields.Add("Name", typeof(string)); listOfFields.Add("Age", typeof(int)); var myType = MyTypeBuilder.CompileResultType(listOfFields); var list = MyTypeBuilder.CreateInstanceIList(myType); var listString = listOfFields.Select(x => x.Key).ToArray(); Type t = typeof(YourObject); // your class define PropertyInfo[] props = t.GetProperties().Where(x => listString.Contains(x.Name)).ToArray(); var data = ListYourObjects(); // your list data // mapping only you need foreach (var item in data) { var myObject = Activator.CreateInstance(myType); foreach (var prop in props) { object name = t.GetProperty(prop.Name).GetValue(item); myType.GetProperty(prop.Name).SetValue(myObject, name, null); } list.Add(myObject); } return Json(list, JsonRequestBehavior.AllowGet); }