/src/LinFu.AOP/NewOperatorInterception/InterceptNewCalls.cs

http://github.com/philiplaureano/LinFu · C# · 72 lines · 59 code · 12 blank · 1 comment · 3 complexity · 9adad6433b1669ea06694c9416607f66 MD5 · raw file

  1. using System.Reflection;
  2. using LinFu.AOP.Cecil.Interfaces;
  3. using LinFu.Reflection.Emit;
  4. using Mono.Cecil;
  5. using Mono.Cecil.Cil;
  6. namespace LinFu.AOP.Cecil
  7. {
  8. internal class InterceptNewCalls : InstructionSwapper, IMethodWeaver
  9. {
  10. private readonly INewObjectWeaver _emitter;
  11. private MethodReference _getCurrentMethod;
  12. public InterceptNewCalls(INewObjectWeaver emitter)
  13. {
  14. _emitter = emitter;
  15. }
  16. public override void AddAdditionalMembers(TypeDefinition host)
  17. {
  18. _emitter.AddAdditionalMembers(host);
  19. }
  20. public override void ImportReferences(ModuleDefinition module)
  21. {
  22. _getCurrentMethod = module.ImportMethod<MethodBase>("GetCurrentMethod",
  23. BindingFlags.Public | BindingFlags.Static);
  24. _emitter.ImportReferences(module);
  25. }
  26. protected override void Replace(Instruction currentInstruction, MethodDefinition method, ILProcessor IL)
  27. {
  28. var constructor = (MethodReference) currentInstruction.Operand;
  29. var concreteType = constructor.DeclaringType;
  30. var parameters = constructor.Parameters;
  31. if (!_emitter.ShouldIntercept(constructor, concreteType, method))
  32. {
  33. // Reuse the old instruction instead of emitting a new one
  34. IL.Append(currentInstruction);
  35. return;
  36. }
  37. _emitter.EmitNewObject(method, IL, constructor, concreteType);
  38. }
  39. public override void AddLocals(MethodDefinition hostMethod)
  40. {
  41. _emitter.AddLocals(hostMethod);
  42. }
  43. protected override bool ShouldReplace(Instruction oldInstruction, MethodDefinition hostMethod)
  44. {
  45. if (oldInstruction.OpCode != OpCodes.Newobj)
  46. return false;
  47. var constructor = (MethodReference) oldInstruction.Operand;
  48. var declaringType = constructor.GetDeclaringType();
  49. return _emitter.ShouldIntercept(constructor, declaringType, hostMethod);
  50. }
  51. public bool ShouldWeave(MethodDefinition item)
  52. {
  53. return item.HasBody;
  54. }
  55. public void Weave(MethodDefinition item)
  56. {
  57. Rewrite(item, item.GetILGenerator(), item.Body.Instructions.ToArray());
  58. }
  59. }
  60. }