Génération de code à la volée
De Banane Atomic
Aller à la navigationAller à la recherche
public class DynamicBuilder { public static TypeBuilder CreateTypeBuilder(string assemblyName, string moduleName, string typeName) { // assemblyName here is not mandatory var assemblyNameObject = new AssemblyName() { Name = assemblyName }; AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyNameObject, AssemblyBuilderAccess.Run); // sauvegarder l'assembly dans un fichier AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyNameObject, AssemblyBuilderAccess.RunAndSave, filePath); ModuleBuilder module = assemblyBuilder.DefineDynamicModule(moduleName); // il n'est pas nécessaire de reconstruire à chaque fois un assemblage et un module pour définir un type // le module peut être réutilisé pour définir plusieurs types var type = module.DefineType(typeName, TypeAttributes.Public | TypeAttributes.Class, typeof(BaseClass)); type.AddInterfaceImplementation(typeof(IInterface)); return type; } public static void AddProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType) { FieldBuilder fieldBuilder = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private); PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null); MethodBuilder getPropMthdBldr = typeBuilder.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 = typeBuilder.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); } } |
var typeBuilder = DynamicBuilder.CreateTypeBuilder("AAA", "MMM", "TTT"); DynamicBuilder.AddProperty(typeBuilder, "PPP", typeof(string)); Type generetedType = typeBuilder.CreateType(); dynamic generetedObject = Activator.CreateInstance(generetedType); generetedObject.PPP = "VVV"; |