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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| // create a dynamic assembly and module
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name ="tmpAssembly";
AssemblyBuilder assemblyBuilder = System.Threading.Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder module = assemblyBuilder.DefineDynamicModule("tmpModule");
// create a new type builder
TypeBuilder typeBuilder = module.DefineType("BindableRowCellCollection", TypeAttributes.Public | TypeAttributes.Class);
// Loop over the attributes that will be used as the properties names in out new type
for(int i = 0; i < pFeature.Fields.FieldCount; i++)
{
string propertyName = pFeature.Fields.get_Field(i).Name;
object val = pFeature.get_Value(i);
Type type = GetNewObjectType(propertyName, module, da);
// Generate a private field
FieldBuilder field = typeBuilder.DefineField("_" + propertyName, type, FieldAttributes.Private);
// Generate a public property
PropertyBuilder property =
typeBuilder.DefineProperty(propertyName,
PropertyAttributes.None,
type,
new Type[0]);
//Create the custom attribute to set the description.
Type[] ctorParams = new Type[] { typeof(string) };
ConstructorInfo classCtorInfo =
typeof(DescriptionAttribute).GetConstructor(ctorParams);
CustomAttributeBuilder myCABuilder = new CustomAttributeBuilder(
classCtorInfo,
new object[] {"This is the long description of this property." });
property.SetCustomAttribute(myCABuilder);
//Set the default value.
ctorParams = new Type[] { type };
classCtorInfo = typeof(DefaultValueAttribute).GetConstructor(ctorParams);
if(type.IsEnum)
{
//val contains the text version of the enum. Parse it to the enumeration value.
object o = Enum.Parse(type, val.ToString(), true);
myCABuilder = new CustomAttributeBuilder(
classCtorInfo,
new object[] { o });
}
else
{
myCABuilder = new CustomAttributeBuilder(
classCtorInfo,
new object[] { val });
}
property.SetCustomAttribute(myCABuilder);
// The property set and property get methods require a special set of attributes:
MethodAttributes GetSetAttr =
MethodAttributes.Public |
MethodAttributes.HideBySig;
// Define the"get" accessor method for current private field.
MethodBuilder currGetPropMthdBldr =
typeBuilder.DefineMethod("get_value",
GetSetAttr,
type,
Type.EmptyTypes);
// Intermediate Language stuff...
ILGenerator currGetIL = currGetPropMthdBldr.GetILGenerator();
currGetIL.Emit(OpCodes.Ldarg_0);
currGetIL.Emit(OpCodes.Ldfld, field);
currGetIL.Emit(OpCodes.Ret);
// Define the"set" accessor method for current private field.
MethodBuilder currSetPropMthdBldr =
typeBuilder.DefineMethod("set_value",
GetSetAttr,
null,
new Type[] { type });
// Again some Intermediate Language stuff...
ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
currSetIL.Emit(OpCodes.Ldarg_0);
currSetIL.Emit(OpCodes.Ldarg_1);
currSetIL.Emit(OpCodes.Stfld, field);
currSetIL.Emit(OpCodes.Ret);
// Last, we must map the two methods created above to our PropertyBuilder to
// their corresponding behaviors,"get" and"set" respectively.
property.SetGetMethod(currGetPropMthdBldr);
property.SetSetMethod(currSetPropMthdBldr);
}
// Generate our type
Type generatedType = typeBuilder.CreateType(); |