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 100 101
| public static class Proxy
{
private static Dictionary<Type, Type> mappings = new Dictionary<Type, Type>();
public static Type GetProxyType<T>()
{
var type = typeof(T);
return (GetProxyType(type));
}
public static Type GetProxyType(Type type)
{
if (mappings.ContainsKey(type)) return mappings[type];
AssemblyName name = new AssemblyName();
name.Name = "ObjectProxies";
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);
foreach (PropertyInfo propertyInfo in type.GetProperties().Where(p => p.CanWrite && p.CanRead))
{
PropertyBuilder property = proxy.DefineProperty(propertyInfo.Name, propertyInfo.Attributes, propertyInfo.PropertyType, null);
property.SetGetMethod(BuildGetProperty(proxy, type, propertyInfo.Name, propertyInfo.PropertyType));
property.SetSetMethod(BuildSetProperty(proxy, type, propertyInfo.Name, propertyInfo.PropertyType));
}
return mappings[type] = proxy.CreateType();
}
public static MethodBuilder BuildSetProperty(TypeBuilder type, Type baseType, string propertyName, Type propertyType)
{
MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig;
MethodBuilder method = type.DefineMethod("set_" + propertyName, methodAttributes);
MethodInfo method1 = baseType.GetMethod("set_" + propertyName,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
null,
new Type[]{ propertyType },
null
);
MethodInfo method2 = typeof(Entity).GetMethod("RaisePropertyChanged",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
null,
new Type[]{ typeof(String) },
null
);
method.SetReturnType(typeof(void));
method.SetParameters(propertyType);
ParameterBuilder value = method.DefineParameter(1, ParameterAttributes.None, "value");
ILGenerator gen = method.GetILGenerator();
gen.Emit(OpCodes.Nop);
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Call, method1);
gen.Emit(OpCodes.Nop);
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldstr, propertyName);
gen.Emit(OpCodes.Call, method2);
gen.Emit(OpCodes.Nop);
gen.Emit(OpCodes.Ret);
return method;
}
public static MethodBuilder BuildGetProperty(TypeBuilder type, Type baseType, string propertyName, Type propertyType)
{
MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig;
MethodBuilder method = type.DefineMethod("get_" + propertyName, methodAttributes);
MethodInfo method1 = baseType.GetMethod("get_" + propertyName,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
null,
new Type[]{ },
null
);
method.SetReturnType(propertyType);
ILGenerator gen = method.GetILGenerator();
Label label10 = gen.DefineLabel();
gen.Emit(OpCodes.Nop);
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Call, method1);
gen.Emit(OpCodes.Stloc_0);
gen.Emit(OpCodes.Br_S, label10);
gen.MarkLabel(label10);
gen.Emit(OpCodes.Ldloc_0);
gen.Emit(OpCodes.Ret);
return method;
}
} |