ey all,
I'm in the process of creating a method of
tracking whenever an objects properties are changed. Since
its not possible to alter
existing types I decided to used a proxy generated using
Reflection.Emit which inherits from the object needed
Person p = (Person)ProxyBuilder.Construct(typeof(Person));
this proxy builder overrides the properties of Person and
adds in the nessecary code to trigger the property changed
event.
This is the code to generate the proxy
public static Type Construct(Type type)
{
AssemblyName name = new AssemblyName();
name.Name = "ObjectServerProxies";
AssemblyBuilder assembly =
AppDomain.CurrentDomain.DefineDynamicAssembly(name ,
AssemblyBuilderAccess.Run);
ModuleBuilder module = assembly.DefineDynamicModule
("Proxies");
TypeBuilder proxy = module.DefineType(type.Name
+ "Proxy", TypeAttributes.Public |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit,
type);
ConstructorBuilder constructor =
proxy.DefineConstructor(MethodAttributes.Public,
CallingConventions.Standard, new Type[0]);
ILGenerator constructorIL =
constructor.GetILGenerator();
ConstructorInfo baseConstructor =
type.GetConstructor(new Type[0]);
constructorIL.Emit(OpCodes.Ldarg_0);
constructorIL.Emit(OpCodes.Call, baseConstructor);
constructorIL.Emit(OpCodes.Ret);
foreach(PropertyInfo propertyInfo in
type.GetProperties())
{
PropertyBuilder property =
proxy.DefineProperty(propertyInfo.Name,
propertyInfo.Attributes, propertyInfo.PropertyType, null);
MethodAttributes attributes =
MethodAttributes.Public | MethodAttributes.HideBySig |
MethodAttributes.SpecialName |
MethodAttributes.Virtual;
MethodBuilder getMethod =
proxy.DefineMethod("get_" + propertyInfo.Name, attributes,
propertyInfo.PropertyType, null);
ILGenerator getIL =
getMethod.GetILGenerator();
getIL.Emit(OpCodes.Ldarg_0);
getIL.Emit(OpCodes.Call,
propertyInfo.GetGetMethod());
getIL.Emit(OpCodes.Ret);
MethodBuilder setMethod =
proxy.DefineMethod("set_" + propertyInfo.Name, attributes,
typeof(void), new
Type[]{propertyInfo.PropertyType});
ILGenerator setIL =
setMethod.GetILGenerator();
setIL.Emit(OpCodes.Ldarg_0);
setIL.Emit(OpCodes.Ldarg_1);
setIL.Emit(OpCodes.Call,
propertyInfo.GetSetMethod());
setIL.Emit(OpCodes.Ldarg_0);
setIL.Emit(OpCodes.Ldstr,
propertyInfo.Name);
setIL.Emit(OpCodes.Newobj, typeof
(PropertyChangedEventArgs));
MethodInfo onPropertyChanged = typeof
(MappedObject).GetMethod("OnPropertyChanged",
BindingFlags.NonPublic |
BindingFlags.Instance);
setIL.Emit(OpCodes.Call,
onPropertyChanged);
setIL.Emit(OpCodes.Ret);
property.SetGetMethod(getMethod);
property.SetSetMethod(setMethod);
}
return proxy.CreateType();
}
Now the problem I'm having is that the properties are not
being overriden, if I use reflection to iterate though the
proxys properties each
property is showing up twice, one with the declaring type
Person and the other with declaring type PersonProxy,
rather than just the
PersonProxy property being displayed.
Any help appreciated.
Thanks
Nigel Sampson