Exemple #1
0
            public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
            {
                var callResult = Expression.Variable(typeof(object));
                var argsVar    = Expression.Variable(typeof(object[]));

                MethodInfo invoke     = typeof(PrivateAccessor).GetMethod("CallMethod", new[] { typeof(string), typeof(object[]) });
                var        invokeArgs = new List <Expression>
                {
                    Expression.Constant(binder.Name),
                    argsVar
                };

                var typeArgs = MockingUtil.TryGetTypeArgumentsFromBinder(binder);

                if (typeArgs != null)
                {
                    invoke = typeof(PrivateAccessor).GetMethod("CallMethodWithTypeArguments");
                    invokeArgs.Insert(1, Expression.Constant(typeArgs));
                }

                var executionList = new List <Expression>
                {
                    Expression.Assign(argsVar, Expression.NewArrayInit(typeof(object), args.Select(a => Expression.Convert(a.Expression, typeof(object))))),
                    Expression.Assign(callResult, Expression.Call(
                                          Expression.Convert(this.Expression, typeof(PrivateAccessor)), invoke, invokeArgs.ToArray())),
                };

                executionList.AddRange(args
                                       .Select((a, i) => new { expr = a.Expression, i })
                                       .Where(p => p.expr is ParameterExpression)
                                       .Select(p => Expression.Assign(p.expr, Expression.Convert(Expression.ArrayIndex(argsVar, Expression.Constant(p.i)), p.expr.Type))));
                executionList.Add(callResult);

                return(CreateMetaObject(Expression.Block(new[] { argsVar, callResult }, executionList)));
            }
        public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
        {
            var wrapper   = this.Value as ExpressionContainer;
            var valueExpr = wrapper.Expression;

            var typeArgs = MockingUtil.TryGetTypeArgumentsFromBinder(binder);

            var candidateMethods = valueExpr.Type.GetAllMethods()
                                   .Where(m => MockingUtil.StringEqual(m.Name, binder.Name, binder.IgnoreCase) && m.IsStatic == wrapper.IsStatic)
                                   .Where(m => m.GetParameters().Length >= args.Length)
                                   .Select(m =>
            {
                if (typeArgs == null)
                {
                    return(MockingUtil.TrySpecializeGenericMethod(m, args.Select(a => a.RuntimeType).ToArray()) ?? m);
                }
                else
                {
                    return(MockingUtil.TryApplyTypeArguments(m, typeArgs));
                }
            })
                                   .Where(m => m != null)
                                   .Where(m =>
            {
                var methodParams = m.GetParameters();
                for (int i = 0; i < args.Length; ++i)
                {
                    var matcher = UnwrapMatcher(args[i]);
                    if (matcher != null)
                    {
                        var argType = matcher.ReturnType;
                        if (!methodParams[i].ParameterType.IsAssignableFrom(argType))
                        {
                            return(false);
                        }
                    }
                }
                return(true);
            })
                                   .ToArray();

            if (candidateMethods.Length == 0 && args.Length == 0)
            {
                return(DoBindGetMember(binder.ReturnType, binder.Name, binder.IgnoreCase));
            }

            var methodArgs = args.Select(a =>
            {
                var matcher = UnwrapMatcher(a);
                return(matcher != null ? matcher.ReturnType.GetDefaultValue() : a.Value);
            }).ToArray();

            object state;
            var    method = (MethodInfo)MockingUtil.BindToMethod(MockingUtil.Default, candidateMethods, ref methodArgs, null, null, null, out state);

            var memberExpr = Expression.Call(!wrapper.IsStatic ? valueExpr : null, method, args.Select(FromArg).ToArray());

            return(CreateRecorder(memberExpr, binder.ReturnType, BindingRestrictions.GetInstanceRestriction(this.Expression, this.Value)));
        }