예제 #1
0
 private static Expression CreateThrowWithContext(DynamicBuildPlanGenerationContext buildContext, MethodInfo throwMethod)
 {
     return(Expression.Call(
                null,
                throwMethod,
                buildContext.ContextParameter));
 }
예제 #2
0
 private static Expression CreateThrowForReferenceItselfMethodConstructor(DynamicBuildPlanGenerationContext buildContext, string signature)
 {
     return(Expression.Call(
                null,
                ThrowForReferenceItselfConstructorMethod,
                buildContext.ContextParameter,
                Expression.Constant(signature, typeof(string))));
 }
 private IBuilderContext GetContext(IBuilderContext originalContext, NamedTypeBuildKey buildKey, DynamicBuildPlanGenerationContext generatorContext)
 {
     return new BuilderContext(
         strategies.MakeStrategyChain(),
         originalContext.Lifetime,
         originalContext.PersistentPolicies,
         originalContext.Policies,
         buildKey,
         generatorContext);
 }
        public IBuildPlanPolicy CreatePlan(IBuilderContext context, NamedTypeBuildKey buildKey)
        {
            Guard.ArgumentNotNull(buildKey, "buildKey");

            DynamicBuildPlanGenerationContext generatorContext =
                new DynamicBuildPlanGenerationContext(buildKey.Type);

            IBuilderContext planContext = GetContext(context, buildKey, generatorContext);

            planContext.Strategies.ExecuteBuildUp(planContext);

            return new DynamicMethodBuildPlan(generatorContext.GetBuildMethod());
        }
예제 #5
0
        /// <summary>
        /// Construct a build plan.
        /// </summary>
        /// <param name="context">The current build context.</param>
        /// <param name="buildKey">The current build key.</param>
        /// <returns>The created build plan.</returns>
        public IBuildPlanPolicy CreatePlan(IBuilderContext context, NamedTypeBuildKey buildKey)
        {
            Guard.ArgumentNotNull(buildKey, "buildKey");

            DynamicBuildPlanGenerationContext generatorContext =
                new DynamicBuildPlanGenerationContext(buildKey.Type);

            IBuilderContext planContext = GetContext(context, buildKey, generatorContext);

            planContext.Strategies.ExecuteBuildUp(planContext);

            return(new DynamicMethodBuildPlan(generatorContext.GetBuildMethod()));
        }
예제 #6
0
        internal Expression CreateInstanceBuildupExpression(DynamicBuildPlanGenerationContext buildContext, IBuilderContext context)
        {
            var targetTypeInfo = context.BuildKey.Type.GetTypeInfo();

            if (targetTypeInfo.IsInterface)
            {
                return(CreateThrowWithContext(buildContext, ThrowForAttemptingToConstructInterfaceMethod));
            }

            if (targetTypeInfo.IsAbstract)
            {
                return(CreateThrowWithContext(buildContext, ThrowForAttemptingToConstructAbstractClassMethod));
            }

            if (targetTypeInfo.IsSubclassOf(typeof(Delegate)))
            {
                return(CreateThrowWithContext(buildContext, ThrowForAttemptingToConstructDelegateMethod));
            }

            var ss = ((System.Collections.IEnumerable)context.Policies);

            IPolicyList resolverPolicyDestination;
            IConstructorSelectorPolicy selector =
                context.Policies.Get <IConstructorSelectorPolicy>(context.BuildKey, out resolverPolicyDestination);

            SelectedConstructor selectedConstructor = selector.SelectConstructor(context, resolverPolicyDestination);

            if (selectedConstructor == null)
            {
                return(CreateThrowWithContext(buildContext, ThrowForNullExistingObjectMethod));
            }

            string signature = CreateSignatureString(selectedConstructor.Constructor);

            if (selectedConstructor.Constructor.GetParameters().Any(pi => pi.ParameterType.IsByRef))
            {
                return(CreateThrowForNullExistingObjectWithInvalidConstructor(buildContext, signature));
            }

            if (IsInvalidConstructor(targetTypeInfo, context, selectedConstructor))
            {
                return(CreateThrowForReferenceItselfMethodConstructor(buildContext, signature));
            }


            return(Expression.Block(CreateNewBuildupSequence(buildContext, selectedConstructor, signature)));
        }
예제 #7
0
        internal Expression CreateInstanceBuildupExpression(DynamicBuildPlanGenerationContext buildContext, IBuilderContext context)
        {
            var targetTypeInfo = context.BuildKey.Type.GetTypeInfo();

            if (targetTypeInfo.IsInterface)
            {
                return(CreateThrowWithContext(buildContext, ThrowForAttemptingToConstructInterfaceMethod));
            }

            if (targetTypeInfo.IsAbstract)
            {
                return(CreateThrowWithContext(buildContext, ThrowForAttemptingToConstructAbstractClassMethod));
            }

            if (targetTypeInfo.IsSubclassOf(typeof(Delegate)))
            {
                return(CreateThrowWithContext(buildContext, ThrowForAttemptingToConstructDelegateMethod));
            }

            IPolicyList resolverPolicyDestination;
            IConstructorSelectorPolicy selector =
                context.Policies.Get <IConstructorSelectorPolicy>(context.BuildKey, out resolverPolicyDestination);

            SelectedConstructor selectedConstructor = selector.SelectConstructor(context, resolverPolicyDestination);

            if (selectedConstructor == null)
            {
                return(CreateThrowWithContext(buildContext, ThrowForNullExistingObjectMethod));
            }

            string signature = DynamicMethodConstructorStrategy.CreateSignatureString(selectedConstructor.Constructor);

            if (IsInvalidConstructor(selectedConstructor))
            {
                return(CreateThrowForNullExistingObjectWithInvalidConstructor(buildContext, signature));
            }

            // psuedo-code:
            // throw if attempting interface
            // if (context.Existing == null) {
            //   collect parameters
            //   set operation to invoking constructor
            //   context.Existing = new {objectType}({constructorparameter}...)
            //   clear current operation
            // }
            return(Expression.Block(this.CreateNewBuildupSequence(buildContext, selectedConstructor, signature)));
        }
예제 #8
0
        private IEnumerable <Expression> CreateNewBuildupSequence(DynamicBuildPlanGenerationContext buildContext, SelectedConstructor selectedConstructor, string signature)
        {
            var parameterExpressions = this.BuildConstructionParameterExpressions(buildContext, selectedConstructor, signature);
            var newItemExpression    = Expression.Variable(selectedConstructor.Constructor.DeclaringType, "newItem");

            yield return(Expression.Call(null,
                                         SetCurrentOperationToInvokingConstructorMethod,
                                         Expression.Constant(signature),
                                         buildContext.ContextParameter));

            yield return(Expression.Assign(
                             buildContext.GetExistingObjectExpression(),
                             Expression.Convert(
                                 Expression.New(selectedConstructor.Constructor, parameterExpressions),
                                 typeof(object))));

            yield return(buildContext.GetClearCurrentOperationExpression());
        }
예제 #9
0
        /// <summary>
        /// Called during the chain of responsibility for a build operation.
        /// </summary>
        /// <remarks>Existing object is an instance of <see cref="DynamicBuildPlanGenerationContext"/>.</remarks>
        /// <param name="context">The context for the operation.</param>
        public override void PreBuildUp(IBuilderContext context)
        {
            Guard.ArgumentNotNull(context, "context");

            DynamicBuildPlanGenerationContext buildContext =
                (DynamicBuildPlanGenerationContext)context.Existing;

            GuardTypeIsNonPrimitive(context);

            buildContext.AddToBuildPlan(
                Expression.IfThen(
                    Expression.Equal(
                        buildContext.GetExistingObjectExpression(),
                        Expression.Constant(null)),
                    this.CreateInstanceBuildupExpression(buildContext, context)));

            buildContext.AddToBuildPlan(
                Expression.Call(null, SetPerBuildSingletonMethod, buildContext.ContextParameter));
        }
예제 #10
0
        private IEnumerable <Expression> BuildConstructionParameterExpressions(DynamicBuildPlanGenerationContext buildContext, SelectedConstructor selectedConstructor, string constructorSignature)
        {
            int i = 0;
            var constructionParameters = selectedConstructor.Constructor.GetParameters();

            foreach (IDependencyResolverPolicy parameterResolver in selectedConstructor.GetParameterResolvers())
            {
                yield return(buildContext.CreateParameterExpression(
                                 parameterResolver,
                                 constructionParameters[i].ParameterType,
                                 Expression.Call(null,
                                                 SetCurrentOperationToResolvingParameterMethod,
                                                 Expression.Constant(constructionParameters[i].Name, typeof(string)),
                                                 Expression.Constant(constructorSignature),
                                                 buildContext.ContextParameter)));

                i++;
            }
        }
예제 #11
0
        private IEnumerable <Expression> BuildMethodParameterExpressions(DynamicBuildPlanGenerationContext context, SelectedMethod method, string methodSignature)
        {
            int i = 0;
            var methodParameters = method.Method.GetParameters();

            foreach (IDependencyResolverPolicy parameterResolver in method.GetParameterResolvers())
            {
                yield return(context.CreateParameterExpression(
                                 parameterResolver,
                                 methodParameters[i].ParameterType,
                                 Expression.Call(null,
                                                 SetCurrentOperationToResolvingParameterMethod,
                                                 Expression.Constant(methodParameters[i].Name, typeof(string)),
                                                 Expression.Constant(methodSignature),
                                                 context.ContextParameter)));

                i++;
            }
        }
예제 #12
0
 private static Expression CreateThrowForNullExistingObjectWithInvalidConstructor(DynamicBuildPlanGenerationContext buildContext, string signature)
 {
     return(Expression.Call(
                null,
                ThrowForNullExistingObjectWithInvalidConstructorMethod,
                buildContext.ContextParameter,
                Expression.Constant(signature, typeof(string))));
 }
예제 #13
0
        private IEnumerable<Expression> BuildMethodParameterExpressions(DynamicBuildPlanGenerationContext context, SelectedMethod method, string methodSignature)
        {
            int i = 0;
            var methodParameters = method.Method.GetParameters();

            foreach (IDependencyResolverPolicy parameterResolver in method.GetParameterResolvers())
            {
                yield return context.CreateParameterExpression(
                                parameterResolver,
                                methodParameters[i].ParameterType,
                                Expression.Call(null,
                                    SetCurrentOperationToResolvingParameterMethod,
                                    Expression.Constant(methodParameters[i].Name, typeof(string)),
                                    Expression.Constant(methodSignature),
                                    context.ContextParameter));
                i++;
            }
        }
예제 #14
0
 private IBuilderContext GetContext(IBuilderContext originalContext, NamedTypeBuildKey buildKey, DynamicBuildPlanGenerationContext generatorContext)
 {
     return(new BuilderContext(originalContext.Container,
                               strategies.MakeStrategyChain(),
                               originalContext.Lifetime,
                               originalContext.PersistentPolicies,
                               originalContext.Policies,
                               buildKey,
                               generatorContext));
 }