/// <summary> /// 创建一个代理对象 /// </summary> /// <param name="handler"></param> /// <param name="objType"></param> /// <param name="isObjInterface"></param> /// <returns></returns> public Object Create(IProxyInvocationHandler handler, Type objType, bool isObjInterface) { if (isObjInterface) { return(DynamicProxy.NewInstance(AppDomain.CurrentDomain, new Type[] { objType }, handler)); } else { return(DynamicProxy.NewInstance(AppDomain.CurrentDomain, objType.GetInterfaces(), handler)); } }
private static MethodBuilder MakeMethod(TypeBuilder typeBuilder, MethodInfo method, Boolean createPublic) { Int32 methodNum = DynamicProxy.Register(method); Type[] paramTypes = ToTypes(method.GetParameters()); Int32 paramNum = paramTypes.Length; Boolean[] paramsByRef = new Boolean[paramNum]; MethodBuilder b; String name; MethodAttributes methodAttr; if (createPublic) { name = method.Name; methodAttr = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig; } else { name = method.DeclaringType.FullName + "." + method.Name; methodAttr = MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Final; } b = typeBuilder.DefineMethod(name, methodAttr, method.CallingConvention, method.ReturnType, paramTypes); ILGenerator gen = b.GetILGenerator(); LocalBuilder parameters = gen.DeclareLocal(typeof(Object[])); LocalBuilder result = gen.DeclareLocal(typeof(Object)); LocalBuilder retval = null; if (!method.ReturnType.Equals(typeof(void))) { retval = gen.DeclareLocal(method.ReturnType); } gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldfld, FieldInfo_handler); //this.handler gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldc_I4, methodNum); gen.Emit(OpCodes.Call, MethodInfo_GetMethod); gen.Emit(OpCodes.Ldc_I4, paramNum); gen.Emit(OpCodes.Newarr, typeof(Object)); // new Object[] if (paramNum > 0) { gen.Emit(OpCodes.Stloc, parameters); for (Int32 i = 0; i < paramNum; i++) { gen.Emit(OpCodes.Ldloc, parameters); gen.Emit(OpCodes.Ldc_I4, i); gen.Emit(OpCodes.Ldarg, i + 1); if (paramTypes[i].IsByRef) { paramTypes[i] = paramTypes[i].GetElementType(); if (paramTypes[i] == typeofInt8 || paramTypes[i] == typeofBoolean) { gen.Emit(OpCodes.Ldind_I1); } else if (paramTypes[i] == typeofUInt8) { gen.Emit(OpCodes.Ldind_U1); } else if (paramTypes[i] == typeofInt16) { gen.Emit(OpCodes.Ldind_I2); } else if (paramTypes[i] == typeofUInt16 || paramTypes[i] == typeofChar) { gen.Emit(OpCodes.Ldind_U2); } else if (paramTypes[i] == typeofInt32) { gen.Emit(OpCodes.Ldind_I4); } else if (paramTypes[i] == typeofUInt32) { gen.Emit(OpCodes.Ldind_U4); } else if (paramTypes[i] == typeofInt64 || paramTypes[i] == typeofUInt64) { gen.Emit(OpCodes.Ldind_I8); } else if (paramTypes[i] == typeofSingle) { gen.Emit(OpCodes.Ldind_R4); } else if (paramTypes[i] == typeofDouble) { gen.Emit(OpCodes.Ldind_R8); } else if (paramTypes[i].IsValueType) { gen.Emit(OpCodes.Ldobj, paramTypes[i]); } else { gen.Emit(OpCodes.Ldind_Ref); } paramsByRef[i] = true; } else { paramsByRef[i] = false; } if (paramTypes[i].IsValueType) { gen.Emit(OpCodes.Box, paramTypes[i]); } gen.Emit(OpCodes.Stelem_Ref); } gen.Emit(OpCodes.Ldloc, parameters); } // base.Invoke(this, method, parameters); gen.Emit(OpCodes.Callvirt, DynamicProxy_Invoke); gen.Emit(OpCodes.Stloc, result); for (Int32 i = 0; i < paramNum; i++) { if (paramsByRef[i]) { gen.Emit(OpCodes.Ldarg, i + 1); gen.Emit(OpCodes.Ldloc, parameters); gen.Emit(OpCodes.Ldc_I4, i); gen.Emit(OpCodes.Ldelem_Ref); if (paramTypes[i].IsValueType) { #if NET1 gen.Emit(OpCodes.Unbox, paramTypes[i]); gen.Emit(OpCodes.Ldobj, paramTypes[i]); #else gen.Emit(OpCodes.Unbox_Any, paramTypes[i]); #endif } else { gen.Emit(OpCodes.Castclass, paramTypes[i]); } if (paramTypes[i] == typeofInt8 || paramTypes[i] == typeofUInt8 || paramTypes[i] == typeofBoolean) { gen.Emit(OpCodes.Stind_I1); } else if (paramTypes[i] == typeofInt16 || paramTypes[i] == typeofUInt16 || paramTypes[i] == typeofChar) { gen.Emit(OpCodes.Stind_I2); } else if (paramTypes[i] == typeofInt32 || paramTypes[i] == typeofUInt32) { gen.Emit(OpCodes.Stind_I4); } else if (paramTypes[i] == typeofInt64 || paramTypes[i] == typeofUInt64) { gen.Emit(OpCodes.Stind_I8); } else if (paramTypes[i] == typeofSingle) { gen.Emit(OpCodes.Stind_R4); } else if (paramTypes[i] == typeofDouble) { gen.Emit(OpCodes.Stind_R8); } else if (paramTypes[i].IsValueType) { gen.Emit(OpCodes.Stobj, paramTypes[i]); } else { gen.Emit(OpCodes.Stind_Ref); } } } if (!method.ReturnType.Equals(typeof(void))) { gen.Emit(OpCodes.Ldloc, result); if (method.ReturnType.IsValueType) { #if NET1 gen.Emit(OpCodes.Unbox, method.ReturnType); gen.Emit(OpCodes.Ldobj, method.ReturnType); #else gen.Emit(OpCodes.Unbox_Any, method.ReturnType); #endif } else { gen.Emit(OpCodes.Castclass, method.ReturnType); } gen.Emit(OpCodes.Stloc_S, retval); gen.Emit(OpCodes.Ldloc_S, retval); } gen.Emit(OpCodes.Ret); if (!createPublic) { typeBuilder.DefineMethodOverride(b, method); } return(b); }