How to create own dynamic type or dynamic object in C#

How to create own dynamic type or dynamic object in C#

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);
        }

 

Published by

tuanitpro

Tôi là Lê Thanh Tuấn, và tôi chia sẻ những điều mình cho rằng nó là thú vị, hay giúp ích cho bạn!

Leave a Reply