Пример #1
0
        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));
        }
Пример #2
0
        private 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));
        }
Пример #3
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));
        }
Пример #4
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));
        }
Пример #5
0
        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);
            });
        }
Пример #6
0
        private static Func <Expression, LambdaExpression> FixedLambdaFactory(Type target, string method, InjectLambdaSignature signature)
        {
            // retrieve validated factory method once
            var factory = signature.FindFactory(target, method);

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