Beispiel #1
0
        /// <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));
        }
Beispiel #2
0
        /// <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));
        }
Beispiel #3
0
        private bool ShouldInject(MemberInfo member, InjectLambdaMetadata data)
        {
            if (member.DeclaringType is null)
            {
                throw new InvalidOperationException($"Member {member.Name} has no declaring type.");
            }

            // inject only configured or green-listed targets
            return(data.Config || greenlist.Any(member.DeclaringType.IsAssignableFrom));
        }
Beispiel #4
0
        bool ShouldInject(MemberInfo member, InjectLambdaMetadata data)
        {
            // inject only configured...
            if (data.Config)
            {
                return(true);
            }

            if (whitelist == null)
            {
                return(false);
            }

            // ...or white-listed targets
            var info = member.DeclaringType.GetTypeInfo();

            return(whitelist.Any(info.IsAssignableFrom));
        }
        /// <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));
        }
Beispiel #6
0
 private bool ShouldInject(MemberInfo member, InjectLambdaMetadata data)
 {
     // inject only configured or white-listed targets
     return(data.Config || whitelist.Any(member.DeclaringType.IsAssignableFrom));
 }