Вопрос

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.

Это было полезно?

Решение

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top