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