I need to do this question since, I can't proceed with code. I am doing one personal implementation of a ORM, and I avoid to use reflection to create objects whenever possible. Now, regarding to ORM contextualized, normally we get objects from there and we "Track them" through their properties.
Everytime I return object from my ORM I return Proxies, where they extend from the original object and Internally they have 1 field, that points to the ORM for changing tracking purposes.
My question is very simple, I need to create one method that returns the Proxy type that when users interact through object properties, those will behind the scenes talk with the ORM.
I am using Reflection.Emit to this task, and I have I good IL behind the scenes, but seems that the code is not called.
Can you provide me light to solve this? or some technique that I can walk through and see by myself what is wrong?
internal static Type EmitProxy(Type type)
{
TypeBuilder proxy = s_moduleBuilder.DefineType(type.Name + "Impl", TypeAttributes.Public, type);
// define OMapper and IsProxy properties in each instance
PropertyBuilder propProxy = proxy.AddProperty(PROXY_PROPERTY_NAME, typeof(bool));
PropertyBuilder propOMapperInstance = proxy.AddProperty(OMapper_PROPERTY_NAME, typeof(OMapper));
MethodBuilder methodNotifyPropertyChangeBuilder = proxy.AddMethod("NotifyPropertyChange", MethodAttributes.Public, typeof(void), new[] { typeof(string) }, il =>
{
// private void NotifyPropertyChange(string propertyName) {
// this.OMapperProperty.PutObjectForUpdate(proxy, propertyName);
// }
il.Emit(op.Ldarg_0); // push this.
il.Emit(op.Call, propOMapperInstance.GetGetMethod());
// il.Emit(op.Ldarg_0); // push this.
il.Emit(op.Ldstr, "id"); // push propertyName.
il.Emit(op.Call, typeof(OMapperContextExecuter).GetMethod("PutObjectForUpdate", BindingFlags.Public | BindingFlags.Instance));
});
// override base properties
foreach (var pi in type.GetProperties(OMapper.s_PropertiesFlags))
{
// save base setMethod - same logic
MethodInfo SetMethodHook = pi.GetSetMethod();
MethodBuilder overrideSetBuilder = proxy.AddMethod("set_" + pi.Name, SetMethodHook.Attributes, SetMethodHook.ReturnType, new[] { pi.PropertyType }, il =>
{
// maintain the old behavior
il.Emit(op.Ldarg_0); // push this
il.Emit(op.Ldarg_1); // push value
il.Emit(op.Call, SetMethodHook);
il.Emit(op.Ldarg_0); // push this.
il.Emit(op.Ldstr, pi.Name); // push propertyName
il.Emit(op.Call, methodNotifyPropertyChangeBuilder); // push value
});
}
var t = proxy.CreateType();
s_assemblyBuilder.Save(s_assemblyName.Name);
return t;
//
}
Those methods through lambda are just there to refactoring purposes; Inside AddProperty, I define Get/Set methods and create the property.
Aucun commentaire:
Enregistrer un commentaire