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