/// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="typeToBuild"></param> /// <param name="existing"></param> /// <param name="idToBuild"></param> /// <param name="il"></param> protected override void BuildUp(IBuilderContext context, Type typeToBuild, object existing, string idToBuild, ILGenerator il) { IConstructorChooserPolicy ctorChooser = GetConstructorChooser(context, typeToBuild, idToBuild); ConstructorInfo ctor = ctorChooser.ChooseConstructor(typeToBuild); Label existingObjectNotNull = il.DefineLabel(); Label done = il.DefineLabel(); // If existing object (arg 2) is null, call the constructor il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brfalse, existingObjectNotNull); // resolve all constructor parameters... if (ctor != null) { foreach (ParameterInfo parameter in ctor.GetParameters()) { EmitResolveParameter(il, parameter); FixupParameterType(il, parameter.ParameterType); } } // invoke constructor, leaving the new object on the top of the stack... EmitCallConstructor(il, ctor, typeToBuild); // And skip around the else clause il.Emit(OpCodes.Br_S, done); // We have an existing object, just get it on top of the stack il.MarkLabel(existingObjectNotNull); il.Emit(OpCodes.Ldarg_2); il.MarkLabel(done); }
private static IConstructorChooserPolicy GetConstructorChooser(IBuilderContext context, Type typeToBuild, string idToBuild) { IConstructorChooserPolicy ctorChooser = context.Policies.Get <IConstructorChooserPolicy>(typeToBuild, idToBuild); if (ctorChooser == null) { ctorChooser = new DefaultConstructorChooserPolicy(); context.Policies.Set <IConstructorChooserPolicy>(ctorChooser, typeToBuild, idToBuild); } return(ctorChooser); }