Example #1
0
        static Func<object, IInputData, object> GenCommand(MethodInfo methodInfo, IParameterBinders binders)
        {
            var parameters = methodInfo.GetParameters();
            var controllerExpr = Expression.Parameter(typeof(object), "controller");
            var inputDataExpr = Expression.Parameter(typeof(IInputData), "inputData");
            List<ParameterExpression> varExprs = new List<ParameterExpression>();

            IList<ParameterExpression> argExprs = new List<ParameterExpression>();
            List<Expression> codeExprs = new List<Expression>();
            #region handler parameters
            foreach (var paraInfo in parameters)
            {
                var paramTypeInfo = paraInfo.ParameterType.GetTypeInfo();
                var binder = binders.GetOrCreateBinder(paraInfo.ParameterType);
                //var User user = null;
                var paramValueExpr = Expression.Parameter(paraInfo.ParameterType, paraInfo.Name);
                varExprs.Add(paramValueExpr);
                argExprs.Add(paramValueExpr);

                if (paramTypeInfo.IsClass)
                {
                    // user = inputData.GetContextValue(typeof(User)) as User;
                    var getContextValueExpr = Expression.Convert(Expression.Call(controllerExpr, InputDataGetContextValueMethodInfo, Expression.Constant(paraInfo.ParameterType)), paraInfo.ParameterType);
                    var assignExpr = Expression.Assign(paramValueExpr, getContextValueExpr);
                    codeExprs.Add(assignExpr);
                    // if(user==null) user = binder.GetValue("user",inputData) as User;
                    var getBindValueExpr = Expression.Convert(
                        Expression.Call(Expression.Constant(binder), ParameterBinderGetValueMethodInfo, Expression.Constant(paraInfo.Name), inputDataExpr)
                        , paraInfo.ParameterType
                    );
                    var checkExpr = Expression.IfThen(
                        Expression.Equal(paramValueExpr, Expression.Constant(null))
                        , Expression.Assign(paramValueExpr, getBindValueExpr)
                    );
                    codeExprs.Add(checkExpr);
                }
                else
                {
                    //var object userObj = null;
                    var paramValueObjExpr = Expression.Parameter(typeof(object), paraInfo.Name + "Obj");
                    varExprs.Add(paramValueObjExpr);
                    var getBindValueExpr = Expression.Call(Expression.Constant(binder), ParameterBinderGetValueMethodInfo, Expression.Constant(paraInfo.Name), inputDataExpr);
                    // userObj = binder.GetValue("user",inputData);
                    var assignExpr = Expression.Assign(paramValueObjExpr, getBindValueExpr);
                    codeExprs.Add(assignExpr);
                    if (paraInfo.HasDefaultValue)
                    {
                        //if(userObj==null) user = "******" else user = (string)userObj;
                        var checkDefault = Expression.IfThenElse(
                            Expression.Equal(paramValueObjExpr, Expression.Constant(null))
                            , Expression.Assign(paramValueExpr, Expression.Constant(paraInfo.DefaultValue))
                            , Expression.Assign(paramValueExpr, Expression.Convert(paramValueObjExpr, paraInfo.ParameterType))
                        );
                        codeExprs.Add(checkDefault);
                    }
                }
            }
            #endregion

            #region call and return
            Expression resultExpr = null;
            if (methodInfo.ReturnType != null && methodInfo.ReturnType != typeof(void))
            {
                resultExpr = Expression.Call(controllerExpr, methodInfo, argExprs);

            }
            else
            {
                resultExpr = Expression.Constant(null, typeof(object));


            }
            var labelTarget = Expression.Label(typeof(object));
            var returnValueExpr = Expression.Convert(resultExpr, typeof(object));
            var retExpr = Expression.Return(labelTarget, returnValueExpr);
            var labelExpr = Expression.Label(labelTarget, resultExpr);
            codeExprs.Add(retExpr);
            codeExprs.Add(labelExpr);
            #endregion

            Expression block = Expression.Block(varExprs, codeExprs);
            if (block.CanReduce)
            {
                block = block.ReduceAndCheck();
            }
            var lamda = Expression.Lambda<Func<object, IInputData, object>>(block, argExprs);
            return lamda.Compile();
        }
Example #2
0
 public Command(MethodInfo actionInfo,IParameterBinders binders) {
     this.command = GenCommand(actionInfo,binders);
 }