Question

i write some method for create class and property in run time with Reflection.Emit my code is:

     public class DynamicLibraryProperties
        {
            public string PropName { get; set; }
            public Type PropType { get; set; }
            public string DefaultValue { get; set; }
        }

 public class GenerateDynamicClass
    {
        public static void GenerateLegacyStructureObject(string libraryName, string className, List<DynamicLibraryProperties> properties)
        {
            ILGenerator ilgen = default(ILGenerator);
            string library = string.Concat(libraryName, ".dll");
            AssemblyBuilder asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(libraryName), AssemblyBuilderAccess.RunAndSave);
            ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule(libraryName, library);
            TypeBuilder legacyBuilder = modBuilder.DefineType(string.Concat(libraryName, ".", className), TypeAttributes.Class | TypeAttributes.Public);
            //Field Builder - Based on number of months add so many fields 
            foreach (DynamicLibraryProperties p in properties)
            {
                FieldBuilder field = legacyBuilder.DefineField(string.Concat("_", p.PropName), p.PropType, FieldAttributes.Private);
                PropertyBuilder nameProp = legacyBuilder.DefineProperty(p.PropName, PropertyAttributes.HasDefault, p.PropType, null);
                Type[] types = new Type[] { p.PropType };
                dynamic typeConvertor = TypeDescriptor.GetConverter(p.PropType);
                dynamic defaultValue = typeConvertor.ConvertFromString(p.DefaultValue);
                ConstructorInfo ctor = typeof(DefaultValueAttribute).GetConstructor(types);
                CustomAttributeBuilder customAttrib = new CustomAttributeBuilder(ctor, new object[] { defaultValue });
                nameProp.SetCustomAttribute(customAttrib);
                MethodAttributes getAttr = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName;
                MethodBuilder getNameBuilder = legacyBuilder.DefineMethod(string.Concat("get_", p.PropName), getAttr, p.PropType, Type.EmptyTypes);
                ilgen = getNameBuilder.GetILGenerator(); ilgen.Emit(OpCodes.Ldarg_0);
                ilgen.Emit(OpCodes.Ldfld, field);
                ilgen.Emit(OpCodes.Ret);
                MethodBuilder setNameBuilder = legacyBuilder.DefineMethod(string.Concat("set_", p.PropName), getAttr, null, new Type[] { p.PropType });
                ilgen = setNameBuilder.GetILGenerator();
                ilgen.Emit(OpCodes.Ldarg_0); 
                ilgen.Emit(OpCodes.Ldarg_1); 
                ilgen.Emit(OpCodes.Stfld, field); ilgen.Emit(OpCodes.Ret); 
                nameProp.SetGetMethod(getNameBuilder); 
                nameProp.SetSetMethod(setNameBuilder);
            } 
            Type objType = Type.GetType("System.Object");
            ConstructorInfo objCtor = objType.GetConstructor(Type.EmptyTypes);
            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Call, objCtor);
            ilgen.Emit(OpCodes.Ret); 
            legacyBuilder.CreateType(); 
            asmBuilder.Save(library);
        }


    }

and use this code like this

 List<DynamicLibraryProperties> props = new List<DynamicLibraryProperties>();
            props.Add(new DynamicLibraryProperties
                          {
                              PropName = "201203", PropType = typeof(float),DefaultValue = "0"
                          });
            props.Add(new DynamicLibraryProperties { PropName = "201204", PropType = typeof(float) ,DefaultValue = "0"});

            GenerateDynamicClass.GenerateLegacyStructureObject("test", "test", props);

Now i want create instance of Test class and set value for property value but i don't no how to do it, please help me , thanks all.

Était-ce utile?

La solution

You can use Activator.CreateInstance for this, for that you need Type of your test class. Change the method as below.

public static Type GenerateLegacyStructureObject(string libraryName, string className, List<DynamicLibraryProperties> properties)
{
    //your code
    Type t = legacyBuilder.CreateType(); 
    asmBuilder.Save(library);
    return t;
}

Then use it like this

Type testType = GenerateDynamicClass.GenerateLegacyStructureObject("test", "test", props);
object test = Activator.CreateInstance(testType);

Hope this helps

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top