MethodDefinition AddPostInjectMethod( string name, ReflectionTypeInfo.InjectMethodInfo postInjectInfo, TypeDefinition typeDef, TypeReference genericTypeDef) { var methodDef = new MethodDefinition( name, MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Static, _module.TypeSystem.Void); var p1 = new ParameterDefinition(_module.TypeSystem.Object); p1.Name = "P_0"; methodDef.Parameters.Add(p1); var p2 = new ParameterDefinition(_objectArrayType); p2.Name = "P_1"; methodDef.Parameters.Add(p2); var body = methodDef.Body; var processor = body.GetILProcessor(); AddPostInjectMethodBody(processor, postInjectInfo, typeDef, genericTypeDef); typeDef.Methods.Add(methodDef); return(methodDef); }
void AddInjectableMethodInstructions( List <Instruction> instructions, ReflectionTypeInfo.InjectMethodInfo injectMethod, TypeDefinition typeDef, TypeReference genericTypeDef, MethodDefinition methodDef) { instructions.Add(Instruction.Create(OpCodes.Ldnull)); instructions.Add(Instruction.Create(OpCodes.Ldftn, methodDef.ChangeDeclaringType(genericTypeDef))); instructions.Add(Instruction.Create(OpCodes.Newobj, _funcPostInject)); instructions.Add(Instruction.Create(OpCodes.Ldc_I4, injectMethod.Parameters.Count)); instructions.Add(Instruction.Create(OpCodes.Newarr, _injectableInfoType)); for (int i = 0; i < injectMethod.Parameters.Count; i++) { var injectableInfo = injectMethod.Parameters[i].InjectableInfo; instructions.Add(Instruction.Create(OpCodes.Dup)); instructions.Add(Instruction.Create(OpCodes.Ldc_I4, i)); EmitNewInjectableInfoInstructions( instructions, injectableInfo, typeDef); instructions.Add(Instruction.Create(OpCodes.Stelem_Ref)); } instructions.Add(Instruction.Create(OpCodes.Ldstr, injectMethod.MethodInfo.Name)); instructions.Add(Instruction.Create(OpCodes.Newobj, _injectMethodInfoConstructor)); }
void AddPostInjectMethodBody( ILProcessor processor, ReflectionTypeInfo.InjectMethodInfo postInjectInfo, TypeDefinition typeDef, TypeReference genericTypeDef) { processor.Emit(OpCodes.Nop); TypeReference declaringTypeDef; MethodReference actualMethodDef; if (!TryFindLocalMethod( genericTypeDef, postInjectInfo.MethodInfo.Name, out declaringTypeDef, out actualMethodDef)) { throw Assert.CreateException(); } processor.Emit(OpCodes.Ldarg_0); processor.Emit(OpCodes.Castclass, declaringTypeDef); for (int k = 0; k < postInjectInfo.Parameters.Count; k++) { var injectInfo = postInjectInfo.Parameters[k]; processor.Emit(OpCodes.Ldarg_1); processor.Emit(OpCodes.Ldc_I4, k); processor.Emit(OpCodes.Ldelem_Ref); EmitCastOperation(processor, injectInfo.ParameterInfo.ParameterType, typeDef.GenericParameters); } processor.Emit(OpCodes.Callvirt, actualMethodDef); processor.Emit(OpCodes.Ret); }