/src/LinFu.AOP/Emitters/GetMethodReplacementProvider.cs

http://github.com/philiplaureano/LinFu · C# · 63 lines · 39 code · 7 blank · 17 comment · 3 complexity · e2abf9a61e1b32da5f4822621b2ab9d1 MD5 · raw file

  1. using System;
  2. using LinFu.AOP.Cecil.Interfaces;
  3. using LinFu.AOP.Interfaces;
  4. using Mono.Cecil;
  5. using Mono.Cecil.Cil;
  6. namespace LinFu.AOP.Cecil
  7. {
  8. /// <summary>
  9. /// Represents a class that emits the instructions that obtain an instance-level
  10. /// <see cref="IMethodReplacementProvider" /> instance.
  11. /// </summary>
  12. public class GetMethodReplacementProvider : IInstructionEmitter
  13. {
  14. private readonly MethodDefinition _hostMethod;
  15. private readonly VariableDefinition _methodReplacementProvider;
  16. private readonly Func<ModuleDefinition, MethodReference> _resolveGetProviderMethod;
  17. /// <summary>
  18. /// Initializes a new instance of the <see cref="GetMethodReplacementProvider" /> class.
  19. /// </summary>
  20. /// <param name="methodReplacementProvider">
  21. /// The local variable that contains the <see cref="IMethodReplacementProvider" />
  22. /// instance.
  23. /// </param>
  24. /// <param name="hostMethod">The target method.</param>
  25. /// <param name="resolveGetProviderMethod">The functor that will resolve the GetProvider method.</param>
  26. public GetMethodReplacementProvider(VariableDefinition methodReplacementProvider, MethodDefinition hostMethod,
  27. Func<ModuleDefinition, MethodReference> resolveGetProviderMethod)
  28. {
  29. if (methodReplacementProvider.VariableType.FullName != typeof(IMethodReplacementProvider).FullName)
  30. throw new ArgumentException();
  31. _methodReplacementProvider = methodReplacementProvider;
  32. _hostMethod = hostMethod;
  33. _resolveGetProviderMethod = resolveGetProviderMethod;
  34. }
  35. /// <summary>
  36. /// Emits the instructions that obtain the <see cref="IMethodReplacementProvider" /> instance.
  37. /// </summary>
  38. /// <param name="IL">The <see cref="ILProcessor" /> instance.</param>
  39. public void Emit(ILProcessor IL)
  40. {
  41. var method = _hostMethod;
  42. var declaringType = method.DeclaringType;
  43. var module = declaringType.Module;
  44. if (!method.HasThis)
  45. {
  46. IL.Emit(OpCodes.Ldnull);
  47. IL.Emit(OpCodes.Stloc, _methodReplacementProvider);
  48. return;
  49. }
  50. var getProvider = _resolveGetProviderMethod(module);
  51. IL.Emit(OpCodes.Ldarg_0);
  52. IL.Emit(OpCodes.Callvirt, getProvider);
  53. IL.Emit(OpCodes.Stloc, _methodReplacementProvider);
  54. }
  55. }
  56. }