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