public Func <Container, object> CreateConstructorInjectionLambda(CachedConstructorInfo injectionConstructor)
        {
            Type returnType = typeof(object);

            ParameterExpression containerArg       = Expression.Parameter(typeof(Container), "container");
            ParameterExpression constructionResult = Expression.Variable(returnType, "constructionResult");

            var returnLabel = Expression.Label(returnType, "returnLabel");

            List <Expression> methodBody = new List <Expression>
            {
                Expression.Assign(constructionResult,
                                  Expression.New(injectionConstructor,
                                                 BuildInjectionLambdaArguments(
                                                     containerArg,
                                                     injectionConstructor.Query(MethodBaseQueries.GetParameters).Select(p => (CachedParameterInfo)p).ToArray()))),

                Expression.Return(returnLabel, constructionResult, returnType),
                Expression.Label(returnLabel, constructionResult)
            };

            return(Expression
                   .Lambda <Func <Container, object> >(Expression.Block(new List <ParameterExpression> {
                constructionResult
            }, methodBody), containerArg)
                   .Compile());
        }
        public Func <Container, object> CreateInstanceFactory(CachedType type, InjectionOptions containerInjectionOptions, InjectionOptions injectionOptions)
        {
            CachedConstructorInfo constructor =
                (injectionOptions.ChooseInjectionConstructor ?? containerInjectionOptions.ChooseInjectionConstructor)(
                    type.Query(ClassQueries.GetPublicConstructors)
                    .Select(c => (CachedConstructorInfo)c));

            var constructLamda = constructor.Query(info => lambdaGenerator.CreateConstructorInjectionLambda(info));

            List <Action <Container, object> > injectionLambdas = new List <Action <Container, object> >();

            var chooseInjectionMethods = injectionOptions.ChooseInjectionMethods ??
                                         containerInjectionOptions.ChooseInjectionMethods;

            if (chooseInjectionMethods != null)
            {
                var injectionMethods = chooseInjectionMethods(type
                                                              .Query(ClassQueries.GetPublicImplementedMethods).Select(m => (CachedMethodInfo)m));

                foreach (var cachedMethodInfo in injectionMethods)
                {
                    var methodInjectionLambda = cachedMethodInfo.Query(m =>
                                                                       lambdaGenerator.CreateMethodInjectionLambda(type, cachedMethodInfo));

                    injectionLambdas.Add(methodInjectionLambda);
                }
            }

            var chooseInjectionProperties = injectionOptions.ChooseInjectionProperties ??
                                            containerInjectionOptions.ChooseInjectionProperties;

            if (chooseInjectionProperties != null)
            {
                var injectionProperties = chooseInjectionProperties(type.Query(ClassQueries.GetPublicImplementedProperties).Select(p => (CachedPropertyInfo)p)).ToArray();

                if (injectionProperties.Length > 0)
                {
                    injectionLambdas.Add(lambdaGenerator.CreatePropertyInjectionLambda(type, injectionProperties));
                }
            }

            return(CombineConstructorInjectionAndMemberInjectionLambdas(constructLamda, injectionLambdas.ToArray()));
        }