1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| public static object CreateDynamicClass(XDocument doc)
{
var asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("DynAsm"), AssemblyBuilderAccess.RunAndSave);
var modBuilder = asmBuilder.DefineDynamicModule("DynMod", "DynAsm.dll", true);
var type = modBuilder.DefineType("DynType", TypeAttributes.Public);
//Create the ctor
var ctor = type.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
var il = ctor.GetILGenerator();
foreach (var field in doc.Root.Elements())
{
if (field.Attribute("name") == null || field.Attribute("value") == null)
continue;
var name = field.Attribute("name").Value;
var value = field.Attribute("value").Value;
//Define a new field
var fieldInfo = type.DefineField("_" + name, typeof(string), FieldAttributes.Private);
//Define a new property
var propertyInfo = type.DefineProperty(name, PropertyAttributes.HasDefault, typeof(string), Type.EmptyTypes);
//Bind property getter to the field
var getter = type.DefineMethod("get_" + name, MethodAttributes.Public, typeof(string), Type.EmptyTypes);
var ilGet = getter.GetILGenerator();
ilGet.Emit(OpCodes.Ldarg_0); // Push current instance on the stack
ilGet.Emit(OpCodes.Ldfld, fieldInfo); // Push field value
ilGet.Emit(OpCodes.Ret); //return
//Bind property setter to the field
var setter = type.DefineMethod("set_" + name, MethodAttributes.Public, null, new[] { typeof(string) });
var ilSet = setter.GetILGenerator();
ilSet.Emit(OpCodes.Ldarg_0); // Push current instance on the stack
ilSet.Emit(OpCodes.Ldarg_1); // Push value
ilSet.Emit(OpCodes.Stfld, fieldInfo); // Save value to field
ilSet.Emit(OpCodes.Ret);
propertyInfo.SetGetMethod(getter);
propertyInfo.SetSetMethod(setter);
//Set field value
il.Emit(OpCodes.Ldarg_0); // Push current instance on the stack
il.Emit(OpCodes.Ldstr, value); //Push string
il.Emit(OpCodes.Stfld, fieldInfo); // Set field with popped value
}
il.Emit(OpCodes.Ret);
return Activator.CreateInstance(type.CreateType());
} |
Partager