static Func <Expression, LambdaExpression> FixedLambdaFactory(InjectLambdaAttribute metadata, Type target, string method, Type[] args, Type result, bool instance)
        {
            // apply configuration, if any
            if (metadata != null)
            {
                if (metadata.Target != null)
                {
                    target = metadata.Target;
                }
                if (!string.IsNullOrEmpty(metadata.Method))
                {
                    method = metadata.Method;
                }
            }

            // retrieve validated factory method once
            var factory = FactoryMethod(target, method, args, result, instance);

            if (factory.IsStatic)
            {
                // compile factory call for performance reasons :-)
                return(Expression.Lambda <Func <Expression, LambdaExpression> >(
                           Expression.Call(factory), Expression.Parameter(typeof(Expression))).Compile());
            }

            // call actual target object, compiles every time during execution... :-|
            return(value => Expression.Lambda <Func <LambdaExpression> >(Expression.Call(value, factory)).Compile()());
        }
        public static InjectLambdaMetadata Create(MethodInfo method)
        {
            var metadata = InjectLambdaAttribute.GetCustomAttribute(method);

            var lambdaFactory = new Lazy <Func <Expression, LambdaExpression> >(() =>
                                                                                LambdaFactory(method, metadata ?? InjectLambdaAttribute.None));

            return(new InjectLambdaMetadata(metadata != null, lambdaFactory));
        }
        public static InjectLambdaMetadata Create(PropertyInfo property)
        {
            var metadata = InjectLambdaAttribute.GetCustomAttribute(property)
                           ?? InjectLambdaAttribute.GetCustomAttribute(property.GetGetMethod(true));

            var lambdaFactory = new Lazy <Func <Expression, LambdaExpression> >(() =>
                                                                                LambdaFactory(property, metadata ?? InjectLambdaAttribute.None));

            return(new InjectLambdaMetadata(metadata != null, lambdaFactory));
        }
Beispiel #4
0
        static Func <Expression, LambdaExpression> LambdaFactory(MethodInfo method, InjectLambdaAttribute metadata)
        {
            // retrieve method's signature
            var signature = new InjectLambdaSignature(method);

            // special ultra-fast treatment for static methods and sealed classes
            if (method.IsStatic || method.DeclaringType.IsSealed)
            {
                return(FixedLambdaFactory(metadata.Target ?? method.DeclaringType, metadata.Method ?? method.Name, signature));
            }

            // dynamic but not that fast treatment for other stuff
            return(DynamicLambdaFactory(method.Name, signature));
        }
        static Func <Expression, LambdaExpression> LambdaFactory(MethodInfo method, InjectLambdaAttribute metadata)
        {
            // retrieve method's signature
            var args   = method.GetParameters().Select(p => p.ParameterType).ToArray();
            var result = method.ReturnParameter.ParameterType;

            // special ultra-fast treatment for static methods and sealed classes
            if (method.IsStatic || method.DeclaringType.GetTypeInfo().IsSealed)
            {
                return(FixedLambdaFactory(metadata, method.DeclaringType, method.Name, args, result, !method.IsStatic));
            }

            // dynamic but not that fast treatment for other stuff
            return(DynamicLambdaFactory(method.Name, args, result));
        }
        private static Func <Expression, LambdaExpression> DynamicLambdaFactory(string method, InjectLambdaSignature signature)
        {
            return(value =>
            {
                // retrieve actual target object, compiles every time and needs reflection too... :-(
                var targetObject = Expression.Lambda <Func <object> >(Expression.Convert(value, typeof(object))).Compile()();

                // retrieve actual target type at runtime, whatever it may be
                var target = targetObject.GetType();

                // actual method may provide different information
                var concreteMethod = signature.FindMatch(target, method);

                // configuration over convention, if any
                var metadata = InjectLambdaAttribute.GetCustomAttribute(concreteMethod) ?? InjectLambdaAttribute.None;

                // retrieve validated factory method
                var factory = signature.FindFactory(target, metadata.Method ?? method);

                // finally call lambda factory *uff*
                return (LambdaExpression)factory.Invoke(targetObject, null);
            });
        }
        private static Func <Expression, LambdaExpression> LambdaFactory(PropertyInfo property, InjectLambdaAttribute metadata)
        {
            // retrieve method's signature
            var signature = new InjectLambdaSignature(property);

            // apply "Expr" convention for property "overloading"
            var method = metadata.Target == null ? property.Name + "Expr" : property.Name;

            // special treatment for super-heroic property getters
            return(FixedLambdaFactory(metadata.Target ?? property.DeclaringType, metadata.Method ?? method, signature));
        }
        static Func <Expression, LambdaExpression> LambdaFactory(PropertyInfo property, InjectLambdaAttribute metadata)
        {
            // retrieve method's signature
            var args   = new[] { property.DeclaringType };
            var result = property.PropertyType;

            // special treatment for super-heroic property getters
            return(FixedLambdaFactory(metadata, property.DeclaringType, property.Name, args, result, false));
        }
Beispiel #9
0
        private static Func <Expression?, LambdaExpression?> LambdaFactory(PropertyInfo property, InjectLambdaAttribute metadata)
        {
            if (property.DeclaringType is null)
            {
                throw new InvalidOperationException($"Property {property.Name} has no declaring type.");
            }

            // retrieve method's signature
            var signature = new InjectLambdaSignature(property);

            // apply "Expr" convention for property "overloading"
            var method = metadata.Target is null ? property.Name + "Expr" : property.Name;

            // special treatment for super-heroic property getters
            return(FixedLambdaFactory(metadata.Target ?? property.DeclaringType, metadata.Method ?? method, signature));
        }
Beispiel #10
0
        private static Func <Expression?, LambdaExpression?> LambdaFactory(MethodInfo method, InjectLambdaAttribute metadata)
        {
            if (method.DeclaringType is null)
            {
                throw new InvalidOperationException($"Method {method.Name} has no declaring type.");
            }

            // retrieve method's signature
            var signature = new InjectLambdaSignature(method);

            // special ultra-fast treatment for static methods and sealed classes
            if (method.IsStatic || method.DeclaringType.IsSealed)
            {
                return(FixedLambdaFactory(metadata.Target ?? method.DeclaringType, metadata.Method ?? method.Name, signature));
            }

            // dynamic but not that fast treatment for other stuff
            return(DynamicLambdaFactory(method, signature));
        }