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

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

                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();
            }
            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);
        }
Exemple #2
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());
        }
Exemple #3
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++;
            }
        }
Exemple #4
0
 private static bool IsInvalidConstructor(SelectedConstructor selectedConstructor)
 {
     return(selectedConstructor.Constructor.GetParameters().Any(pi => pi.ParameterType.IsByRef));
 }