/// <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); }
/// <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); }