public ActionGenerationParameterBindContext(ActionGenerationContext context, ParameterInfo par) : base(context) { this.ParameterInfo = par; this.NullableChecker = new NullableTypes(par.ParameterType); this.LocalExpression = Expression.Parameter(this.ParameterType,par.Name); this.GetItemExpression = Expression.Call(this.ArgumentsExpression, ArgumentGetItemMethodInfo, Expression.Constant(par.Name)); }
public IAction Generate(MethodInfo method) { if (!method.IsPublic) return null; //标记了NoAction的方法跳过 var noAction = method.GetCustomAttribute<NonActionAttribute>(); if (noAction != null) return null; var buildContext = new ActionGenerationContext(method, this.BinderFactory); return Generate(buildContext); }
protected ActionGenerationContext(ActionGenerationContext context) { this.ActionMethodInfo = context.ActionMethodInfo; this.ArgumentsExpression = context.ArgumentsExpression; this.RequestExpression = context.RequestExpression; this.ContextExpression = context.ContextExpression; this.CodeExpressions = context.CodeExpressions; this.LocalVarExpressions = context.LocalVarExpressions; this.BinderFactory = context.BinderFactory; }
/// <summary> /// 根据上下文,生成一个Action /// </summary> /// <param name="cmdContext"></param> /// <returns></returns> IAction Generate(ActionGenerationContext cmdContext) { //获取所有参数 var parameters = cmdContext.ActionMethodInfo.GetParameters(); //函数调用的参数列表 var argExprs = new List<ParameterExpression>(); //循环所有参数 foreach (var par in parameters) { #region 生成为每个参数赋值的表达式 //构建参数上下文 var parContext = new ActionGenerationParameterBindContext(cmdContext,par); //把参数变量添加到变量表中 cmdContext.LocalVarExpressions.Add(parContext.LocalExpression); argExprs.Add(parContext.LocalExpression); //生成绑定参数值的表达式 if (parContext.NullableChecker.IsNullable) { GenerateNullableBindCodes(parContext); } else { GenerateNonullableBindCodes(parContext); } #endregion } #region 生成函数调用 controllerInstance.Insert(username,password); var instanceExpr = cmdContext.ControllerInstanceExpression; var instanceConvertExpr = Expression.Convert(instanceExpr,cmdContext.ActionMethodInfo.DeclaringType); var callExpr = Expression.Call(instanceConvertExpr, cmdContext.ActionMethodInfo, argExprs); cmdContext.CodeExpressions.Add(callExpr); #endregion //根据Action Method的不同返回值类型,生成不同的Action return GenerateReturn(cmdContext,callExpr); }
/// <summary> /// 根据Action Method的不同返回值类型,生成不同的Action /// </summary> /// <param name="cmdContext"></param> /// <param name="callExpr"></param> /// <returns></returns> IAction GenerateReturn(ActionGenerationContext cmdContext, MethodCallExpression callExpr) { var retType = cmdContext.ActionMethodInfo.ReturnType; var labelTarget = Expression.Label(retType); if (cmdContext.ActionMethodInfo.ReturnType.FullName.StartsWith("System.Task")) { } else { var retExpr = Expression.Return(labelTarget, callExpr); LabelExpression labelExpr = Expression.Label(labelTarget); cmdContext.CodeExpressions.Add(labelExpr); Expression blockExpr = Expression.Block(cmdContext.LocalVarExpressions, cmdContext.CodeExpressions); if (blockExpr.CanReduce) blockExpr.ReduceAndCheck(); if (cmdContext.ActionMethodInfo.ReturnType == typeof(void)) { var lamda = Expression.Lambda<Action<object, IArguments, IRequest, Context>>(blockExpr, cmdContext.ControllerInstanceExpression, cmdContext.ArgumentsExpression, cmdContext.RequestExpression, cmdContext.ContextExpression); var func = lamda.Compile(); return new NoresultSyncAction(cmdContext.ActionMethodInfo, func); } else { var lamda = Expression.Lambda<Func<object, IArguments, IRequest, Context,object>>(blockExpr, cmdContext.ControllerInstanceExpression, cmdContext.ArgumentsExpression, cmdContext.RequestExpression, cmdContext.ContextExpression); var func = lamda.Compile(); return new ResultSyncAction(cmdContext.ActionMethodInfo, func); } } return null; //var returnValueExpr = Expression.Convert(resultExpr, typeof(object)); }