public List <MethodDefinition> GetCodeProvidingMethoDefinition(MethodCodeInjectingCodeProviderArgument codeProviderArgument) { var method = codeProviderArgument.Method; var methodName = method.Name; var methodBaseType = method.DeclaringComponent.Name; var methodCall = string.Empty; var handlers = from t in AssemblyDefinition.ReadAssembly(Assembly.GetExecutingAssembly().Location). CustomAttributes.AsQueryable() where t.AttributeType.FullName == typeof(ExceptionHandlerAttribute).FullName select t; var matchHandlers = from t in handlers where t.ConstructorArguments.Any(item => item.Value.ToString().Equals(String.Concat(methodBaseType, ".", methodName))) select t; var returnMethods = new List <MethodDefinition>(); foreach (var item in matchHandlers) { methodCall = item.ConstructorArguments.Last().Value.ToString(); var type = AssemblyDefinition.ReadAssembly(Assembly.GetExecutingAssembly().Location).MainModule.Types.First(x => x.Name == "MethodInjectionCodeProvider"); returnMethods.Add(type.Methods.First(x => x.Name == methodCall)); } return(returnMethods); }
public void Inject(MethodDefinition method, MethodCodeInjectingCodeProviderArgument codeProviderArgument, ILogger logger, MethodInjectionPlace injectionPlace, CustomInstructionsInjection injectNewInstructions) { var callInfoCollection = codeProvider.GetCallInfo(codeProviderArgument, method.Module); if (!method.HasBody) { throw new ArgumentException("Method does not contain body."); } logger.Notice($"Injecting method call before exit of method '{method.FullName}'."); newInstructions.Clear(); if (injectionPlace == MethodInjectionPlace.InCatchBlock) { GenerateInstructionsForInjectedCallInTryCatchBlock(method, newInstructions, callInfoCollection[0].MethodReferenceToBeCalled, callInfoCollection[0].CallArguments); } else { GenerateInstructionsForInjectedCall(newInstructions, callInfoCollection[0].MethodReferenceToBeCalled, callInfoCollection[0].CallArguments); } foreach (var callInfo in callInfoCollection) { injectNewInstructions(method.Body, newInstructions, callInfo.MethodReferenceToBeCalled.Resolve()); } }
public void InjectInCatchBlock(MethodDefinition method, MethodCodeInjectingCodeProviderArgument codeProviderArgument, ILogger logger, MethodInjectionPlace injectionPlace) { Inject( method, codeProviderArgument, logger, injectionPlace, (body, newInstruction, call) => body.AddInstructionsInCatchBlock(newInstruction, call)); }
public void InjectBeforeExit(MethodDefinition method, MethodCodeInjectingCodeProviderArgument codeProviderArgument, ILogger logger, MethodInjectionPlace injectionPlace) { Inject( method, codeProviderArgument, logger, injectionPlace, (body, newInstruction, call) => body.AddInstructionsBeforeExit(newInstructions)); }
public List <CodeProviderInjectionInfo> GetCallInfo(MethodCodeInjectingCodeProviderArgument codeProviderArgument, ModuleDefinition destinationModule) { List <MethodDefinition> methods = GetCodeProvidingMethoDefinition(codeProviderArgument); List <CodeProviderInjectionInfo> returnCallInfo = new List <CodeProviderInjectionInfo>(); foreach (var methodInfo in methods) { var methodArguments = CodeProviderCallArgument.EmptyCollection; /* * methodArguments = new CodeProviderCallArgument[] * { * CodeProviderCallArgument.CreateStateArgument("state", GetStateType(), codeProviderArgument.StateField), * CodeProviderCallArgument.CreateParameterArgument("value", typeof(Exception), methodInfo.Parameters[1]) * }; */ methodArguments = new CodeProviderCallArgument[] { CodeProviderCallArgument.CreateStateArgument("state", GetStateType(), codeProviderArgument.StateField) }; var methodReference = GetAndCheckCodeProvidingMethodReferenceDefinition(methodInfo, methodArguments, destinationModule); if (methodReference.ContainsGenericParameter) { var genericArgumentTypes = GetCodeProvidingMethodGenericArgumentTypes(codeProviderArgument); var genericMethod = new GenericInstanceMethod(methodReference); genericMethod.GenericArguments.AddRange(genericArgumentTypes); methodReference = genericMethod; } CheckCodeProvidingMethodArguments(methodArguments); returnCallInfo.Add(new CodeProviderInjectionInfo(methodReference, methodArguments)); } return(returnCallInfo); }
public void InjectInFinallyBlock(MethodDefinition method, MethodCodeInjectingCodeProviderArgument codeProviderArgument, ILogger logger) { throw new InvalidOperationException($"Under construction injection place specified."); }
public abstract MethodInfo GetCodeProvidingMethod(MethodCodeInjectingCodeProviderArgument codeProviderArgument);
public virtual TypeReference[] GetCodeProvidingMethodGenericArgumentTypes(MethodCodeInjectingCodeProviderArgument codeProviderArgument) { throw new NotImplementedException($"For usage of generic code providing method {nameof(GetCodeProvidingMethodGenericArgumentTypes)} must be properly implemented."); }
public abstract CodeProviderCallArgument[] GetCodeProvidingMethodArguments(MethodCodeInjectingCodeProviderArgument codeProviderArgument);