/// <summary> /// Emit the required IL instructions to the new method. /// </summary> private DynamicMethod BuildTestMethod(Type fixtureType, string methodName, MethodBodyReader reader) { Type exceptionType = typeof(Exception); Type exceptionCollectionType = typeof(Dictionary <int, Exception>); ConstructorInfo exceptionCollectionTypeConstructor = exceptionCollectionType.GetConstructor(Type.EmptyTypes); MethodInfo exceptionCollectionTypeAddMethod = exceptionCollectionType.GetMethod("Add"); List <List <ILInstruction> > sections = GetMethodSections(reader); ushort freeLocalIndex = reader.GetFreeLocalIndex(); ushort localExceptionCollection = freeLocalIndex++; ushort localException = freeLocalIndex++; DynamicMethod testMethod = new DynamicMethod(methodName, exceptionCollectionType, new Type[] { fixtureType }, fixtureType); ILGenerator generator = testMethod.GetILGenerator(); DeclareLocalVariableTypes(generator, reader); // Instantiate exception collection. generator.DeclareLocal(exceptionCollectionType); generator.Emit(OpCodes.Nop); generator.Emit(OpCodes.Newobj, exceptionCollectionTypeConstructor); generator.Emit(OpCodes.Stloc_S, localExceptionCollection); foreach (List <ILInstruction> sect in sections) { // Start the try block. generator.BeginExceptionBlock(); foreach (ILInstruction instruction in sect) { instruction.EmitTo(generator); } // If no exception was thrown add a null reference to the collection. generator.Emit(OpCodes.Ldloc_S, localExceptionCollection); generator.Emit(OpCodes.Ldc_I4, sect[0].Offset); generator.Emit(OpCodes.Ldnull); generator.Emit(OpCodes.Callvirt, exceptionCollectionTypeAddMethod); generator.Emit(OpCodes.Nop); // Catch Exception. generator.BeginCatchBlock(exceptionType); // Save thrown exception. generator.DeclareLocal(exceptionType); generator.Emit(OpCodes.Stloc_S, localException); generator.Emit(OpCodes.Nop); // Add the exception to the collection. generator.Emit(OpCodes.Ldloc_S, localExceptionCollection); generator.Emit(OpCodes.Ldc_I4, sect[0].Offset); generator.Emit(OpCodes.Ldloc_S, localException); generator.Emit(OpCodes.Callvirt, exceptionCollectionTypeAddMethod); generator.Emit(OpCodes.Nop); // Exit the try block. generator.EndExceptionBlock(); } generator.Emit(OpCodes.Ldloc_S, localExceptionCollection); generator.Emit(OpCodes.Ret); return(testMethod); }