private static void EncapsulateMethod(AssemblyDefinition assembly, ModuleDefinition module, TypeDefinition type, MethodDefinition method, string overrideName = null, string overrideMethod = nameof(AOPProcessor.OnMethod)) { // New body for current method (capsule) var newMethodBody = new List <Instruction>(); newMethodBody.Add(Instruction.Create(method.IsStatic ? OpCodes.Ldnull : OpCodes.Ldarg_0)); // ldnull / ldarg_0 newMethodBody.Add(Instruction.Create(OpCodes.Ldtoken, type)); newMethodBody.Add(Instruction.Create(OpCodes.Call, typeof(Type).GetMonoMethod(module, nameof(Type.GetTypeFromHandle)))); var mName = method.Name; if (!string.IsNullOrEmpty(overrideName)) { mName = overrideName; } newMethodBody.Add(Instruction.Create(OpCodes.Ldstr, mName)); newMethodBody.Add(Instruction.Create(OpCodes.Ldc_I4, method.Parameters.Count)); newMethodBody.Add(Instruction.Create(OpCodes.Newarr, module.ImportReference(typeof(object)))); for (var num = 0; num < method.Parameters.Count; num++) { var param = method.Parameters[num]; var pType = param.ParameterType; newMethodBody.Add(Instruction.Create(OpCodes.Dup)); newMethodBody.Add(Instruction.Create(OpCodes.Ldc_I4, num)); newMethodBody.Add(Instruction.Create(OpCodes.Ldarg, param)); if (param.ParameterType.IsValueType || param.ParameterType.IsGenericParameter) { newMethodBody.Add(Instruction.Create(OpCodes.Box, pType)); } newMethodBody.Add(Instruction.Create(OpCodes.Stelem_Ref)); } if (module.HasType(typeof(AOPProcessor))) { newMethodBody.Add(Instruction.Create(OpCodes.Call, module.GetType(typeof(AOPProcessor)) .GetMethod(overrideMethod))); } else { newMethodBody.Add(Instruction.Create(OpCodes.Call, typeof(AOPProcessor).GetMonoMethod(module, overrideMethod))); } if (method.ReturnType.FullName != typeof(void).FullName) { if (method.ReturnType.IsValueType) { newMethodBody.Add(Instruction.Create(OpCodes.Unbox_Any, method.ReturnType)); } } else { newMethodBody.Add(Instruction.Create(OpCodes.Pop)); } newMethodBody.Add(Instruction.Create(OpCodes.Ret)); // Create new method var internalMethod = new MethodDefinition(method.Name + AOPProcessor.APPENDIX, method.Attributes, method.ReturnType); foreach (var param in method.Parameters) { var newParam = new ParameterDefinition(param.Name, param.Attributes, param.ParameterType); newParam.HasDefault = false; newParam.IsOptional = false; internalMethod.Parameters .Add(newParam); } // Copy generic parameters foreach (var genericParameter in method.GenericParameters) { internalMethod.GenericParameters .Add(new GenericParameter(genericParameter.Name, internalMethod)); } var bodyClone = new MethodBody(method); bodyClone.AppendInstructions(newMethodBody); bodyClone.MaxStackSize = 8; // Replace method bodies internalMethod.Body = method.Body; method.Body = bodyClone; type.Methods.Add(internalMethod); }