/src/LinFu.AOP/Emitters/GetClassMethodReplacementProvider.cs

http://github.com/philiplaureano/LinFu · C# · 74 lines · 41 code · 8 blank · 25 comment · 0 complexity · c799ebdca609d76d846a20c30a7d74ac MD5 · raw file

  1. using System;
  2. using LinFu.AOP.Cecil.Interfaces;
  3. using LinFu.AOP.Interfaces;
  4. using LinFu.Reflection.Emit;
  5. using Mono.Cecil;
  6. using Mono.Cecil.Cil;
  7. namespace LinFu.AOP.Cecil
  8. {
  9. /// <summary>
  10. /// Represents a class that emits the instructions that obtain a class-level <see cref="IMethodReplacementProvider" />
  11. /// instance.
  12. /// </summary>
  13. public class GetClassMethodReplacementProvider : IInstructionEmitter
  14. {
  15. private readonly VariableDefinition _classMethodReplacementProvider;
  16. private readonly VariableDefinition _invocationInfo;
  17. private readonly Func<ModuleDefinition, MethodReference> _resolveGetProviderMethod;
  18. /// <summary>
  19. /// Initializes a new instance of the <see cref="GetClassMethodReplacementProvider" /> class.
  20. /// </summary>
  21. /// <param name="parameters">The method body rewriter paramters that describe the </param>
  22. /// <param name="resolveGetProviderMethod">
  23. /// The functor that resolves the method that obtains the method replacement
  24. /// provider instance.
  25. /// </param>
  26. public GetClassMethodReplacementProvider(IMethodBodyRewriterParameters parameters,
  27. Func<ModuleDefinition, MethodReference> resolveGetProviderMethod)
  28. {
  29. _invocationInfo = parameters.InvocationInfo;
  30. _classMethodReplacementProvider = parameters.ClassMethodReplacementProvider;
  31. _resolveGetProviderMethod = resolveGetProviderMethod;
  32. }
  33. /// <summary>
  34. /// Initializes a new instance of the <see cref="GetClassMethodReplacementProvider" /> class.
  35. /// </summary>
  36. /// <param name="invocationInfo">The variable that contains the <see cref="IInvocationInfo" /> instance.</param>
  37. /// <param name="classMethodReplacementProvider">The variable that contains the class method replacement provider instance.</param>
  38. /// <param name="resolveGetProviderMethod">
  39. /// The functor that resolves the method that obtains the method replacement
  40. /// provider instance.
  41. /// </param>
  42. public GetClassMethodReplacementProvider(VariableDefinition invocationInfo,
  43. VariableDefinition classMethodReplacementProvider,
  44. Func<ModuleDefinition, MethodReference> resolveGetProviderMethod)
  45. {
  46. _invocationInfo = invocationInfo;
  47. _classMethodReplacementProvider = classMethodReplacementProvider;
  48. _resolveGetProviderMethod = resolveGetProviderMethod;
  49. }
  50. /// <summary>
  51. /// Emits the instructions that obtain a class-level <see cref="IMethodReplacementProvider" /> instance.
  52. /// </summary>
  53. /// <param name="IL">The <see cref="ILProcessor" /> instance that points to the instructions in the method body.</param>
  54. public void Emit(ILProcessor IL)
  55. {
  56. var method = IL.Body.Method;
  57. var module = method.Module;
  58. var getProvider = _resolveGetProviderMethod(module);
  59. var pushThis = method.HasThis ? OpCodes.Ldarg_0 : OpCodes.Ldnull;
  60. IL.Emit(pushThis);
  61. IL.Emit(OpCodes.Ldloc, _invocationInfo);
  62. IL.Emit(OpCodes.Call, getProvider);
  63. IL.Emit(OpCodes.Stloc, _classMethodReplacementProvider);
  64. }
  65. }
  66. }