Beispiel #1
0
 /// <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));
     }
 }
Beispiel #2
0
        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);
        }