示例#1
0
 private static Expression CreateThrowWithContext(DynamicBuildPlanGenerationContext buildContext, MethodInfo throwMethod)
 {
     return(Expression.Call(
                null,
                throwMethod,
                buildContext.ContextParameter));
 }
        /// <summary>
        /// Called during the chain of responsibility for a build operation. The
        /// PreBuildUp method is called when the chain is being executed in the
        /// forward direction.
        /// </summary>
        /// <param name="context">Context of the build operation.</param>
        // FxCop suppression: Validation is done by Guard class
        public override void PreBuildUp(IBuilderContext context)
        {
            DynamicBuildPlanGenerationContext ilContext = (DynamicBuildPlanGenerationContext)(context.Existing);
            IMethodSelectorPolicy             selector  = context.Policies.Get <IMethodSelectorPolicy>(context.BuildKey);

            foreach (SelectedMethod method in selector.SelectMethods(context))
            {
                GuardMethodIsNotOpenGeneric(method.Method);
                GuardMethodHasNoOutParams(method.Method);
                GuardMethodHasNoRefParams(method.Method);

                ParameterInfo[] parameters = method.Method.GetParameters();

                ilContext.EmitLoadExisting();

                int i = 0;
                foreach (string key in method.GetParameterKeys())
                {
                    ilContext.EmitResolveDependency(parameters[i].ParameterType, key);
                    ++i;
                }
                ilContext.IL.EmitCall(OpCodes.Callvirt, method.Method, null);
                if (method.Method.ReturnType != typeof(void))
                {
                    ilContext.IL.Emit(OpCodes.Pop);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Called during the chain of responsibility for a build operation.
        /// </summary>
        /// <param name="context">The context for the operation.</param>
        public override void PreBuildUp(IBuilderContext context)
        {
            DynamicBuildPlanGenerationContext ilContext = (DynamicBuildPlanGenerationContext)(context.Existing);

            IPropertySelectorPolicy selector = context.Policies.Get <IPropertySelectorPolicy>(context.BuildKey);

            foreach (SelectedProperty property in selector.SelectProperties(context))
            {
                // Set the current operation to resolving
                ilContext.IL.Emit(OpCodes.Ldstr, property.Property.Name);
                ilContext.EmitLoadContext();
                ilContext.IL.EmitCall(OpCodes.Call, setCurrentOperationToResolvingPropertyValue, null);

                // Resolve the property value
                ilContext.EmitLoadExisting();
                ilContext.EmitResolveDependency(property.Property.PropertyType, property.Key);

                // Set the current operation to setting
                ilContext.IL.Emit(OpCodes.Ldstr, property.Property.Name);
                ilContext.EmitLoadContext();
                ilContext.IL.EmitCall(OpCodes.Call, setCurrentOperationToSettingProperty, null);

                // Call the property setter
                ilContext.IL.EmitCall(OpCodes.Callvirt, property.Property.GetSetMethod(), null);
            }

            // Clear the current operation
            ilContext.EmitClearCurrentOperation();
        }
示例#4
0
        /// <summary>
        /// Called during the chain of responsibility for a build operation. The
        /// PreBuildUp method is called when the chain is being executed in the
        /// forward direction.
        /// </summary>
        /// <param name="context">Context of the build operation.</param>
        // FxCop suppression: Validation is done by Guard class
        public override void PreBuildUp(IBuilderContext context)
        {
            DynamicBuildPlanGenerationContext ilContext = (DynamicBuildPlanGenerationContext)(context.Existing);
            IMethodSelectorPolicy             selector  = context.Policies.Get <IMethodSelectorPolicy>(context.BuildKey);

            LocalBuilder currentMethodName    = ilContext.IL.DeclareLocal(typeof(string));
            LocalBuilder currentParameterName = ilContext.IL.DeclareLocal(typeof(string));

            ilContext.IL.BeginExceptionBlock();

            foreach (SelectedMethod method in selector.SelectMethods(context))
            {
                ilContext.IL.Emit(OpCodes.Ldstr, GetMethodSignature(method.Method));
                ilContext.IL.Emit(OpCodes.Stloc, currentMethodName);
                ilContext.IL.Emit(OpCodes.Ldnull);
                ilContext.IL.Emit(OpCodes.Stloc, currentParameterName);

                GuardMethodIsNotOpenGeneric(method.Method);
                GuardMethodHasNoOutParams(method.Method);
                GuardMethodHasNoRefParams(method.Method);

                ParameterInfo[] parameters = method.Method.GetParameters();

                ilContext.EmitLoadExisting();

                int i = 0;
                foreach (string key in method.GetParameterKeys())
                {
                    ilContext.IL.Emit(OpCodes.Ldstr, parameters[i].Name);
                    ilContext.IL.Emit(OpCodes.Stloc, currentParameterName);
                    ilContext.EmitResolveDependency(parameters[i].ParameterType, key);
                    ++i;
                }
                ilContext.IL.Emit(OpCodes.Ldnull);
                ilContext.IL.Emit(OpCodes.Stloc, currentParameterName);
                ilContext.IL.EmitCall(OpCodes.Callvirt, method.Method, null);
                if (method.Method.ReturnType != typeof(void))
                {
                    ilContext.IL.Emit(OpCodes.Pop);
                }
            }

            ilContext.IL.BeginCatchBlock(typeof(Exception));

            Label parameterResolveFailed = ilContext.IL.DefineLabel();

            ilContext.IL.Emit(OpCodes.Ldloc, currentParameterName);
            ilContext.IL.Emit(OpCodes.Brtrue, parameterResolveFailed);

            // Failure was in the method call.
            ilContext.IL.Emit(OpCodes.Rethrow);

            ilContext.IL.MarkLabel(parameterResolveFailed);
            ilContext.IL.Emit(OpCodes.Ldloc, currentMethodName);
            ilContext.IL.Emit(OpCodes.Ldloc, currentParameterName);
            ilContext.IL.EmitCall(OpCodes.Call, throwOnParameterResolveFailed, null);

            ilContext.IL.EndExceptionBlock();
        }
 private IBuilderContext GetContext(IBuilderContext originalContext, NamedTypeBuildKey buildKey, DynamicBuildPlanGenerationContext ilContext)
 {
     return new BuilderContext(
         strategies.MakeStrategyChain(),
         originalContext.Lifetime,
         originalContext.PersistentPolicies,
         originalContext.Policies,
         buildKey,
         ilContext);
 }
        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());
        }
        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()));
        }
示例#8
0
        /// <summary>
        /// Called during the chain of responsibility for a build operation.
        /// </summary>
        /// <param name="context">The context for the operation.</param>
        public override void PreBuildUp(IBuilderContext context)
        {
            DynamicBuildPlanGenerationContext ilContext = (DynamicBuildPlanGenerationContext)(context.Existing);

            IPropertySelectorPolicy selector = context.Policies.Get <IPropertySelectorPolicy>(context.BuildKey);

            foreach (SelectedProperty property in selector.SelectProperties(context))
            {
                ilContext.EmitLoadExisting();
                ilContext.EmitResolveDependency(property.Property.PropertyType, property.Key);
                ilContext.IL.EmitCall(OpCodes.Callvirt, property.Property.GetSetMethod(), null);
            }
        }
        /// <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, object buildKey)
        {
            IDynamicBuilderMethodCreatorPolicy methodCreatorPolicy =
                context.Policies.Get <IDynamicBuilderMethodCreatorPolicy>(context.BuildKey);
            DynamicBuildPlanGenerationContext generatorContext =
                new DynamicBuildPlanGenerationContext(
                    BuildKey.GetType(buildKey), methodCreatorPolicy);

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

            planContext.Strategies.ExecuteBuildUp(planContext);

            return(new DynamicMethodBuildPlan(generatorContext.GetBuildMethod()));
        }
        public override void PreBuildUp(IBuilderContext context)
        {
            Guard.ArgumentNotNull(context, "context");

            DynamicBuildPlanGenerationContext buildContext =
                (DynamicBuildPlanGenerationContext)context.Existing;

            IConstructorSelectorPolicy selector =
                context.Policies.Get <IConstructorSelectorPolicy>(context.BuildKey);

            SelectedConstructor selectedCtor = selector.SelectConstructor(context);
            // Method preamble - test if we have an existing object
            // First off, set up jump - if there's an existing object, skip us entirely
            Label existingObjectNotNull = buildContext.IL.DefineLabel();

            buildContext.EmitLoadExisting();
            buildContext.IL.Emit(OpCodes.Ldnull);
            buildContext.IL.Emit(OpCodes.Ceq);
            buildContext.IL.Emit(OpCodes.Brfalse, existingObjectNotNull);

            if (selectedCtor != null)
            {
                // Resolve parameters
                ParameterInfo[] parameters = selectedCtor.Constructor.GetParameters();

                int i = 0;
                foreach (string parameterKey in selectedCtor.GetParameterKeys())
                {
                    buildContext.EmitResolveDependency(parameters[i].ParameterType, parameterKey);
                    ++i;
                }

                // Call the constructor

                buildContext.IL.Emit(OpCodes.Newobj, selectedCtor.Constructor);
                buildContext.EmitStoreExisting();
            }
            else
            {
                // If we get here, object has no constructors. It's either
                // an interface or a primitive (like int). In this case,
                // verify that we have an Existing object, and if not,
                // throw (via helper function).
                buildContext.EmitLoadContext();
                buildContext.IL.EmitCall(OpCodes.Call, throwForNullExistingObject, null);
            }

            buildContext.IL.MarkLabel(existingObjectNotNull);
        }
示例#11
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)));
        }
        /// <summary>
        /// Called during the chain of responsibility for a build operation. The
        /// PreBuildUp method is called when the chain is being executed in the
        /// forward direction.
        /// </summary>
        /// <param name="context">Context of the build operation.</param>
        // FxCop suppression: Validation is done by Guard class
        public override void PreBuildUp(IBuilderContext context)
        {
            DynamicBuildPlanGenerationContext ilContext = (DynamicBuildPlanGenerationContext)(context.Existing);
            IMethodSelectorPolicy             selector  = context.Policies.Get <IMethodSelectorPolicy>(context.BuildKey);

            foreach (SelectedMethod method in selector.SelectMethods(context))
            {
                string signatureString = GetMethodSignature(method.Method);

                GuardMethodIsNotOpenGeneric(method.Method);
                GuardMethodHasNoOutParams(method.Method);
                GuardMethodHasNoRefParams(method.Method);

                ParameterInfo[] parameters = method.Method.GetParameters();

                ilContext.EmitLoadExisting();

                int i = 0;
                foreach (string key in method.GetParameterKeys())
                {
                    // Set the current operation
                    ilContext.IL.Emit(OpCodes.Ldstr, parameters[i].Name);
                    ilContext.IL.Emit(OpCodes.Ldstr, signatureString);
                    ilContext.EmitLoadContext();
                    ilContext.IL.EmitCall(OpCodes.Call, setCurrentOperationToResolvingParameter, null);

                    // Resolve the parameter
                    ilContext.EmitResolveDependency(parameters[i].ParameterType, key);
                    ++i;
                }

                // Set the current operation
                ilContext.IL.Emit(OpCodes.Ldstr, signatureString);
                ilContext.EmitLoadContext();
                ilContext.IL.EmitCall(OpCodes.Call, setCurrentOperationToInvokingMethod, null);

                // Invoke the injection method
                ilContext.IL.EmitCall(OpCodes.Callvirt, method.Method, null);
                if (method.Method.ReturnType != typeof(void))
                {
                    ilContext.IL.Emit(OpCodes.Pop);
                }
            }

            // Clear the current operation
            ilContext.EmitClearCurrentOperation();
        }
示例#13
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());
        }
示例#14
0
        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));
        }
        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++;
            }
        }
示例#16
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++;
            }
        }
        /// <summary>
        /// Called during the chain of responsibility for a build operation.
        /// </summary>
        /// <param name="context">The context for the operation.</param>
        public override void PreBuildUp(IBuilderContext context)
        {
            DynamicBuildPlanGenerationContext ilContext = (DynamicBuildPlanGenerationContext)(context.Existing);

            IPropertySelectorPolicy selector            = context.Policies.Get <IPropertySelectorPolicy>(context.BuildKey);
            LocalBuilder            resolving           = ilContext.IL.DeclareLocal(typeof(bool));
            LocalBuilder            currentPropertyName = ilContext.IL.DeclareLocal(typeof(string));

            ilContext.IL.BeginExceptionBlock();

            foreach (SelectedProperty property in selector.SelectProperties(context))
            {
                // Resolve the property value
                ilContext.IL.Emit(OpCodes.Ldstr, property.Property.Name);
                ilContext.IL.Emit(OpCodes.Stloc, currentPropertyName);
                ilContext.IL.Emit(OpCodes.Ldc_I4_1);
                ilContext.IL.Emit(OpCodes.Stloc, resolving);
                ilContext.EmitLoadExisting();
                ilContext.EmitResolveDependency(property.Property.PropertyType, property.Key);

                // Call the property setter
                ilContext.IL.Emit(OpCodes.Ldc_I4_0);
                ilContext.IL.Emit(OpCodes.Stloc, resolving);
                ilContext.IL.EmitCall(OpCodes.Callvirt, property.Property.GetSetMethod(), null);
            }

            // Catch any exceptions in the setting of the properties
            ilContext.IL.BeginCatchBlock(typeof(Exception));
            Label failedWhileResolving = ilContext.IL.DefineLabel();

            ilContext.IL.Emit(OpCodes.Ldloc, resolving);
            ilContext.IL.Emit(OpCodes.Brtrue, failedWhileResolving);
            ilContext.IL.Emit(OpCodes.Rethrow);

            ilContext.IL.MarkLabel(failedWhileResolving);
            ilContext.IL.Emit(OpCodes.Ldloc, currentPropertyName);
            ilContext.IL.EmitCall(OpCodes.Call, throwOnFailedPropertyValueResolution, null);
            ilContext.IL.EndExceptionBlock();
        }
示例#18
0
        /// <summary>
        /// Called during the chain of responsibility for a build operation.
        /// </summary>
        /// <param name="context">The context for the operation.</param>
        public override void PreBuildUp(IBuilderContext context)
        {
            Guard.ArgumentNotNull(context, "context");
            DynamicBuildPlanGenerationContext ilContext = (DynamicBuildPlanGenerationContext)(context.Existing);

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

            bool shouldClearOperation = false;

            foreach (SelectedProperty property in selector.SelectProperties(context, resolverPolicyDestination))
            {
                shouldClearOperation = true;
                // Set the current operation to resolving
                ilContext.IL.Emit(OpCodes.Ldstr, property.Property.Name);
                ilContext.EmitLoadContext();
                ilContext.IL.EmitCall(OpCodes.Call, setCurrentOperationToResolvingPropertyValue, null);

                // Resolve the property value
                ilContext.EmitLoadExisting();
                ilContext.EmitResolveDependency(property.Property.PropertyType, property.Key);

                // Set the current operation to setting
                ilContext.IL.Emit(OpCodes.Ldstr, property.Property.Name);
                ilContext.EmitLoadContext();
                ilContext.IL.EmitCall(OpCodes.Call, setCurrentOperationToSettingProperty, null);

                // Call the property setter
                ilContext.IL.EmitCall(OpCodes.Callvirt, GetValidatedPropertySetter(property.Property), null);
            }

            // Clear the current operation
            if (shouldClearOperation)
            {
                ilContext.EmitClearCurrentOperation();
            }
        }
 private IEnumerable<Expression> CreateThrowForNullExistingObjectWithInvalidConstructorSequence(DynamicBuildPlanGenerationContext buildContext, string signature)
 {
     yield return Expression.Call(
                             null,
                             throwForNullExistingObjectWithInvalidConstructor,
                             buildContext.ContextParameter,
                             Expression.Constant(signature, typeof(string)));
 }
        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));
        }
        private IEnumerable<Expression> BuildConstructionParameterExpressions(DynamicBuildPlanGenerationContext buildContext, SelectedConstructor selectedConstructor, string constructorSignature)
        {
            int i = 0;
            var constructionParameters = selectedConstructor.Constructor.GetParameters();

            foreach (string parameterKey in selectedConstructor.GetParameterKeys())
            {
                yield return buildContext.CreateParameterExpression(
                                parameterKey,
                                constructionParameters[i].ParameterType,
                                Expression.Call(null,
                                                setCurrentOperationToResolvingParameter,
                                                Expression.Constant(constructionParameters[i].Name, typeof(string)),
                                                Expression.Constant(constructorSignature),
                                                buildContext.ContextParameter
                                                )
                                );
                i++;
            }
        }
        private IEnumerable<Expression> CreateNewBuildupSequence(DynamicBuildPlanGenerationContext buildContext, SelectedConstructor selectedConstructor, string signature)
        {
            var parameterExpressions = BuildConstructionParameterExpressions(buildContext, selectedConstructor, signature);
            var newItemExpression = Expression.Variable(selectedConstructor.Constructor.DeclaringType, "newItem");

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

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

            yield return buildContext.GetClearCurrentOperationExpression();
        }
 private IBuilderContext GetContext(IBuilderContext originalContext, NamedTypeBuildKey buildKey, DynamicBuildPlanGenerationContext generatorContext)
 {
     return(new BuilderContext(
                strategies.MakeStrategyChain(),
                originalContext.Lifetime,
                originalContext.PersistentPolicies,
                originalContext.Policies,
                buildKey,
                generatorContext));
 }
        internal Expression CreateInstanceBuildupExpression(DynamicBuildPlanGenerationContext buildContext, SelectedConstructor selectedConstructor)
        {
            IEnumerable<Expression> buildupSequence;

            string signature = CreateSignatureString(selectedConstructor.Constructor);

            buildupSequence = IsInvalidConstructor(selectedConstructor)?
                                CreateThrowForNullExistingObjectWithInvalidConstructorSequence(buildContext, signature) :
                                CreateNewBuildupSequence(buildContext, selectedConstructor, 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(
                   Expression.Call(null, throwForAttemptingToConstructInterface, buildContext.ContextParameter),
                   Expression.Block(buildupSequence));
        }
        public override void PreBuildUp(IBuilderContext context)
        {
            Guard.ArgumentNotNull(context, "context");

            DynamicBuildPlanGenerationContext buildContext =
                (DynamicBuildPlanGenerationContext)context.Existing;

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

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

            GuardTypeIsNonPrimitive(context, selectedCtor);

            // Method preamble - test if we have an existing object
            // First off, set up jump - if there's an existing object, skip us entirely
            Label existingObjectNotNull = buildContext.IL.DefineLabel();

            if (!buildContext.TypeToBuild.IsValueType)
            {
                buildContext.EmitLoadExisting();
                buildContext.IL.Emit(OpCodes.Brtrue, existingObjectNotNull);
            }

            // Verify we're not attempting to create an instance of an interface
            buildContext.EmitLoadContext();
            buildContext.IL.EmitCall(OpCodes.Call, throwForAttemptingToConstructInterface, null);

            if (selectedCtor != null)
            {
                string signatureString = CreateSignatureString(selectedCtor.Constructor);

                // Resolve parameters
                ParameterInfo[] parameters = selectedCtor.Constructor.GetParameters();

                if (!parameters.Any(pi => pi.ParameterType.IsByRef))
                {
                    int i = 0;
                    foreach (string parameterKey in selectedCtor.GetParameterKeys())
                    {
                        // Set the current operation
                        buildContext.IL.Emit(OpCodes.Ldstr, parameters[i].Name);
                        buildContext.IL.Emit(OpCodes.Ldstr, signatureString);
                        buildContext.EmitLoadContext();
                        buildContext.IL.EmitCall(OpCodes.Call, setCurrentOperationToResolvingParameter, null);

                        // Resolve the parameter
                        buildContext.EmitResolveDependency(parameters[i].ParameterType, parameterKey);
                        ++i;
                    }

                    // Set the current operation
                    buildContext.IL.Emit(OpCodes.Ldstr, signatureString);
                    buildContext.EmitLoadContext();
                    buildContext.IL.EmitCall(OpCodes.Call, setCurrentOperationToInvokingConstructor, null);

                    // Call the constructor
                    buildContext.IL.Emit(OpCodes.Newobj, selectedCtor.Constructor);

                    // Store the existing object
                    buildContext.EmitStoreExisting();

                    // Clear the current operation
                    buildContext.EmitClearCurrentOperation();

                    // Store existing object back into context - makes it available for future resolvers
                    buildContext.EmitLoadContext();
                    buildContext.EmitLoadExisting();
                    if (buildContext.TypeToBuild.IsValueType)
                    {
                        buildContext.IL.Emit(OpCodes.Box, buildContext.TypeToBuild);
                    }
                    buildContext.IL.EmitCall(OpCodes.Callvirt, setExistingInContext, null);

                    // Is this object a per-build singleton? If so, then emit code to stuff in
                    // the appropriate lifetime manager.
                    buildContext.EmitLoadContext();
                    buildContext.IL.EmitCall(OpCodes.Call, setPerBuildSingleton, null);
                }
                else
                {
                    // if we get here the selected constructor has ref or out parameters.
                    buildContext.EmitLoadContext();
                    buildContext.IL.Emit(OpCodes.Ldstr, signatureString);
                    buildContext.IL.EmitCall(OpCodes.Call, throwForNullExistingObjectWithInvalidConstructor, null);
                }
            }
            else
            {
                // If we get here, object has no constructors. It's either
                // an interface or a primitive (like int). In this case,
                // verify that we have an Existing object, and if not,
                // throw (via helper function).
                buildContext.EmitLoadContext();
                buildContext.IL.EmitCall(OpCodes.Call, throwForNullExistingObject, null);
            }

            buildContext.IL.MarkLabel(existingObjectNotNull);
        }
示例#26
0
 private static Expression CreateThrowForNullExistingObjectWithInvalidConstructor(DynamicBuildPlanGenerationContext buildContext, string signature)
 {
     return(Expression.Call(
                null,
                ThrowForNullExistingObjectWithInvalidConstructorMethod,
                buildContext.ContextParameter,
                Expression.Constant(signature, typeof(string))));
 }
示例#27
0
        public override void PreBuildUp(IBuilderContext context)
        {
            Guard.ArgumentNotNull(context, "context");

            DynamicBuildPlanGenerationContext buildContext =
                (DynamicBuildPlanGenerationContext)context.Existing;

            IConstructorSelectorPolicy selector =
                context.Policies.Get <IConstructorSelectorPolicy>(context.BuildKey);

            SelectedConstructor selectedCtor = selector.SelectConstructor(context);
            // Method preamble - test if we have an existing object
            // First off, set up jump - if there's an existing object, skip us entirely
            Label existingObjectNotNull = buildContext.IL.DefineLabel();

            buildContext.EmitLoadExisting();
            buildContext.IL.Emit(OpCodes.Ldnull);
            buildContext.IL.Emit(OpCodes.Ceq);
            buildContext.IL.Emit(OpCodes.Brfalse, existingObjectNotNull);

            // Verify we're not attempting to create an instance of an interface
            buildContext.EmitLoadContext();
            buildContext.IL.EmitCall(OpCodes.Call, throwForAttemptingToConstructInterface, null);

            if (selectedCtor != null)
            {
                string       signatureString      = CreateSignatureString(selectedCtor.Constructor);
                LocalBuilder currentParameterName = buildContext.IL.DeclareLocal(typeof(string));

                // Resolve parameters
                ParameterInfo[] parameters = selectedCtor.Constructor.GetParameters();

                buildContext.IL.BeginExceptionBlock();

                int i = 0;
                foreach (string parameterKey in selectedCtor.GetParameterKeys())
                {
                    buildContext.IL.Emit(OpCodes.Ldstr, parameters[i].Name);
                    buildContext.IL.Emit(OpCodes.Stloc, currentParameterName);
                    buildContext.EmitResolveDependency(parameters[i].ParameterType, parameterKey);
                    ++i;
                }

                // Call the constructor

                buildContext.IL.Emit(OpCodes.Ldnull);
                buildContext.IL.Emit(OpCodes.Stloc, currentParameterName);

                buildContext.IL.Emit(OpCodes.Newobj, selectedCtor.Constructor);
                buildContext.EmitStoreExisting();

                buildContext.IL.BeginCatchBlock(typeof(Exception));
                Label exceptionOccuredInResolution = buildContext.IL.DefineLabel();

                buildContext.IL.Emit(OpCodes.Ldloc, currentParameterName);
                buildContext.IL.Emit(OpCodes.Ldnull);
                buildContext.IL.Emit(OpCodes.Ceq);
                buildContext.IL.Emit(OpCodes.Brfalse, exceptionOccuredInResolution);
                buildContext.IL.Emit(OpCodes.Rethrow);

                buildContext.IL.MarkLabel(exceptionOccuredInResolution);
                buildContext.IL.Emit(OpCodes.Ldloc, currentParameterName);
                buildContext.IL.Emit(OpCodes.Ldstr, signatureString);
                buildContext.EmitLoadContext();
                buildContext.IL.EmitCall(OpCodes.Call, throwForResolutionFailed, null);

                buildContext.IL.EndExceptionBlock();
            }
            else
            {
                // If we get here, object has no constructors. It's either
                // an interface or a primitive (like int). In this case,
                // verify that we have an Existing object, and if not,
                // throw (via helper function).
                buildContext.EmitLoadContext();
                buildContext.IL.EmitCall(OpCodes.Call, throwForNullExistingObject, null);
            }

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

            foreach (string parameterKey in method.GetParameterKeys())
            {
                yield return context.CreateParameterExpression(
                                parameterKey,
                                methodParameters[i].ParameterType,
                                Expression.Call(null,
                                    setCurrentOperationToResolvingParameter,
                                    Expression.Constant(methodParameters[i].Name, typeof(string)),
                                    Expression.Constant(methodSignature),
                                    context.ContextParameter));
                i++;
            }
        }
 private IBuilderContext GetContext(IBuilderContext originalContext, object buildKey, DynamicBuildPlanGenerationContext ilContext)
 {
     return(new BuilderContext(
                strategies.MakeStrategyChain(),
                originalContext.Locator,
                originalContext.Lifetime,
                originalContext.PersistentPolicies,
                originalContext.Policies,
                buildKey,
                ilContext));
 }
 private static Expression CreateThrowWithContext(DynamicBuildPlanGenerationContext buildContext, MethodInfo throwMethod)
 {
     return Expression.Call(
                         null,
                         throwMethod,
                         buildContext.ContextParameter);
 }