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); } } }
/// <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(); }
/// <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())); }
/// <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); }
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(); }
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()); }
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++; } }
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(); }
/// <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); }
private static Expression CreateThrowForNullExistingObjectWithInvalidConstructor(DynamicBuildPlanGenerationContext buildContext, string signature) { return(Expression.Call( null, ThrowForNullExistingObjectWithInvalidConstructorMethod, buildContext.ContextParameter, Expression.Constant(signature, typeof(string)))); }
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); }