/// <inheritdoc /> protected override Expression VisitMethodCall(MethodCallExpression node) { if (node is null) { throw new ArgumentNullException(nameof(node)); } // cache "meta-data" for performance reasons var data = Cache.GetOrAdd(node.Method, _ => InjectLambdaMetadata.Create(node.Method)); if (ShouldInject(node.Method, data)) { var lambda = data.Lambda(node.Object); if (lambda is null) { throw new InvalidOperationException($"Lambda factory for {node.Method.Name} returns null."); } // rebind expression parameters for current arguments var binders = lambda.Parameters.Zip(node.Arguments, (p, a) => new ParameterBinder(p, a)); return(Visit(binders.Aggregate(lambda.Body, (e, b) => b.Visit(e)))); } return(base.VisitMethodCall(node)); }
/// <inheritdoc /> protected override Expression VisitMember(MemberExpression node) { if (node == null) { throw new ArgumentNullException(nameof(node)); } var property = node.Member as PropertyInfo; if (property?.GetMethod() != null && property.SetMethod() == null) { // cache "meta-data" for performance reasons var data = cache.GetOrAdd(property, _ => InjectLambdaMetadata.Create(property)); if (ShouldInject(property, data)) { var lambda = data.Lambda(null); // only one parameter for property getter var argument = lambda.Parameters.Single(); // rebind expression for single (!) lambda argument var binder = new ParameterBinder(argument, node.Expression); return(Visit(binder.Visit(lambda.Body))); } } return(base.VisitMember(node)); }
/// <inheritdoc /> protected override Expression VisitMethodCall(MethodCallExpression node) { if (node?.Method != null) { // cache "meta-data" for performance reasons var data = cache.GetOrAdd(node.Method, m => InjectLambdaMetadata.Create((MethodInfo)m)); if (ShouldInject(node.Method, data)) { var lambda = data.Lambda(node.Object); // rebind expression parameters for current arguments var binders = lambda.Parameters.Zip(node.Arguments, (p, a) => new ParameterBinder(p, a)); return(Visit(binders.Aggregate(lambda.Body, (e, b) => b.Visit(e)))); } } return(base.VisitMethodCall(node)); }