Exemplo n.º 1
0
        /// <summary>
        /// 生成属性的代理方法
        /// </summary>
        /// <param name="iL">IL生成器</param>
        /// <param name="type">被代理的类</param>
        /// <param name="methodInfo">被代理的方法,Get或Set方法</param>
        /// <param name="propertyInfo">当前被代理的属性</param>
        /// <param name="aspectContextField">类的上下文</param>
        /// <param name="fieldBuilder">使用的拦截器字段</param>
        /// <param name="actionAttr">使用的拦截器</param>
        public static void PropertyProxy(ILGenerator iL, Type type, MethodInfo methodInfo, PropertyInfo propertyInfo, FieldBuilder aspectContextField, FieldBuilder fieldBuilder, ActionAttribute actionAttr)
        {
            Type returnType = methodInfo.ReturnType;                                                    // 返回类型
            bool isSet      = returnType == typeof(void) ? true : false;
            Type paramTypes = methodInfo.GetParameters().Select(x => x.ParameterType).FirstOrDefault(); // 参数列表
            // 五个步骤:
            // * 为上下文设置参数
            // * 执行 拦截器的 Before()
            // * 执行被代理了类的方法
            // * 执行拦截器的 After()
            // * 返回值(如果有)


            // 预先定义部分变量
            LocalBuilder tmpAspectContextBodyField = iL.DeclareLocal(typeof(AspectContextBody)); // 上下文实例,堆栈在 Stloc_0

            if (returnType != typeof(void))                                                      // 如果有返回值时
            {
                iL.DeclareLocal(returnType);                                                     // 用于接收返回结果,堆栈在 Stloc_1
            }
            // 创建一个新的上下文
            iL.Emit(OpCodes.Ldarg_0);
            iL.Emit(OpCodes.Ldfld, aspectContextField);
            iL.Emit(OpCodes.Callvirt, typeof(AspectContextBody).GetMethod($"get_{nameof(AspectContextBody.NewInstance)}"));
            iL.Emit(OpCodes.Stloc_0);       // 存到堆栈 0

            // ①
            // IsProperty = true
            iL.Emit(OpCodes.Ldloc_0);
            iL.Emit(OpCodes.Ldc_I4_1);  // 0 false 1 true
            iL.Emit(OpCodes.Callvirt, typeof(AspectContextBody).GetMethod($"set_{nameof(AspectContextBody.IsProperty)}"));
            // PropertyInfo
            iL.Emit(OpCodes.Ldloc_0);
            iL.Emit(OpCodes.Ldarg_0);
            iL.Emit(OpCodes.Call, typeof(object).GetMethod("GetType"));
            iL.Emit(OpCodes.Ldstr, propertyInfo.Name);
            iL.Emit(OpCodes.Call, typeof(Type).GetMethod(nameof(type.GetProperty), new Type[] { typeof(string) }));
            iL.Emit(OpCodes.Callvirt, typeof(AspectContextBody).GetMethod($"set_{nameof(AspectContextBody.PropertyInfo)}"));
            // PropertyValue
            // 如果是Set方法,那么在此处即可获得值
            if (isSet)
            {
                iL.Emit(OpCodes.Ldloc_0);
                EmitHelper.EmitOne(iL, paramTypes);
                iL.Emit(OpCodes.Callvirt, typeof(AspectContextBody).GetMethod($"set_{nameof(AspectContextBody.PropertyValue)}"));
            }


            // ② 方法执行前
            iL.Emit(OpCodes.Ldarg_0);
            iL.Emit(OpCodes.Ldfld, fieldBuilder);
            iL.Emit(OpCodes.Ldloc_0);
            iL.Emit(OpCodes.Callvirt, actionAttr.GetType().GetMethod(nameof(ActionAttribute.Before)));
            iL.Emit(OpCodes.Nop);
            // ③ 执行方法
            if (isSet)
            {
                iL.Emit(OpCodes.Ldarg_0);
                iL.Emit(OpCodes.Ldloc_0);
                iL.Emit(OpCodes.Callvirt, typeof(AspectContextBody).GetMethod($"get_{nameof(AspectContextBody.PropertyValue)}"));
                if (returnType.IsValueType)
                {
                    iL.Emit(OpCodes.Box, methodInfo.GetParameters().Select(x => x.ParameterType).First());
                }
                else if (returnType != typeof(object))
                {
                    iL.Emit(OpCodes.Castclass, methodInfo.GetParameters().Select(x => x.ParameterType).First());
                }
            }
            else
            {
                iL.Emit(OpCodes.Ldloc_0);
                iL.Emit(OpCodes.Ldarg_0);
            }
            iL.Emit(OpCodes.Call, methodInfo);


            // 有返回值时,使用上下文存储
            if (returnType != typeof(void))
            {
                // 值类型需要装箱
                if (returnType.IsValueType)
                {
                    iL.Emit(OpCodes.Box, returnType);
                }
                else if (returnType != typeof(object))
                {
                    iL.Emit(OpCodes.Castclass, returnType);
                }
                iL.Emit(OpCodes.Callvirt, typeof(AspectContextBody).GetMethod($"set_{nameof(AspectContextBody.PropertyValue)}"));
            }


            // ④ 执行方法后
            iL.Emit(OpCodes.Ldarg_0);
            iL.Emit(OpCodes.Ldfld, fieldBuilder);
            iL.Emit(OpCodes.Ldloc_0);
            iL.Emit(OpCodes.Callvirt, actionAttr.GetType().GetMethod(nameof(ActionAttribute.After)));

            if (returnType != typeof(void))
            {
                if (returnType.IsValueType)
                {
                    iL.Emit(OpCodes.Unbox_Any, methodInfo.ReturnType);
                }
                else
                {
                    iL.Emit(OpCodes.Castclass, methodInfo.ReturnType);
                }
                iL.Emit(OpCodes.Stloc_1);
                iL.Emit(OpCodes.Ldloc_1);       // 取出堆栈中的返回值
            }
            else
            {
                iL.Emit(OpCodes.Pop);
            }
            // ⑤
            iL.Emit(OpCodes.Ret);
        }
Exemplo n.º 2
0
 /// <summary>
 /// Set 代理
 /// </summary>
 public static void PropertySetProxy(ILGenerator iL, Type type, MethodInfo getMethod, PropertyInfo propertyInfo, FieldBuilder aspectContextField, FieldBuilder fieldBuilder, ActionAttribute actionAttr)
 {
     PropertyProxy(iL, type, getMethod, propertyInfo, aspectContextField, fieldBuilder, actionAttr);
 }