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