/src/LinFu.IoC/Configuration/MethodBuilder.cs

http://github.com/philiplaureano/LinFu · C# · 83 lines · 42 code · 10 blank · 31 comment · 3 complexity · 21966a1347bccc1b2246724df339e35d MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Reflection.Emit;
  6. namespace LinFu.IoC.Configuration
  7. {
  8. /// <summary>
  9. /// A class that dynamically generates calls to a <see cref="MethodInfo" /> instance.
  10. /// </summary>
  11. public class MethodBuilder : BaseMethodBuilder<MethodInfo>
  12. {
  13. /// <summary>
  14. /// Pushes the method target onto the evaluation stack.
  15. /// </summary>
  16. /// <param name="IL">The <see cref="ILGenerator" /> of the method body.</param>
  17. /// <param name="method">The target method.</param>
  18. protected override void PushInstance(ILGenerator IL, MethodInfo method)
  19. {
  20. if (method.IsStatic)
  21. return;
  22. IL.Emit(OpCodes.Ldarg_0);
  23. }
  24. /// <summary>
  25. /// Pushes the method arguments onto the stack.
  26. /// </summary>
  27. /// <param name="IL">The <see cref="ILGenerator" /> of the target method body.</param>
  28. /// <param name="targetMethod">The target method that will be invoked.</param>
  29. protected override void PushMethodArguments(ILGenerator IL, MethodBase targetMethod)
  30. {
  31. var parameterTypes = (from p in targetMethod.GetParameters()
  32. select p.ParameterType).ToArray();
  33. var offset = targetMethod.IsStatic ? 0 : 1;
  34. // Push the method arguments onto the stack
  35. var parameterCount = parameterTypes.Length;
  36. for (var index = 0; index < parameterCount; index++) IL.Emit(OpCodes.Ldarg, index + offset);
  37. }
  38. /// <summary>
  39. /// Determines the return type from the target <paramref name="method" />.
  40. /// </summary>
  41. /// <param name="method">The target method itself.</param>
  42. /// <returns>The method return type.</returns>
  43. protected override Type GetReturnType(MethodInfo method)
  44. {
  45. return method.ReturnType;
  46. }
  47. /// <summary>
  48. /// Determines the parameter types of the dynamically generated method.
  49. /// </summary>
  50. /// <param name="existingMethod">The target method.</param>
  51. /// <param name="parameterTypes">The target method argument types.</param>
  52. /// <returns>The list of <see cref="System.Type" /> objects that describe the signature of the method to generate.</returns>
  53. /// <remarks>This override will add an additional parameter type to accomodate the method target.</remarks>
  54. protected override IList<Type> GetParameterList(MethodInfo existingMethod, Type[] parameterTypes)
  55. {
  56. var parameterList = new List<Type>();
  57. if (!existingMethod.IsStatic)
  58. parameterList.Add(existingMethod.DeclaringType);
  59. parameterList.AddRange(parameterTypes);
  60. return parameterList;
  61. }
  62. /// <summary>
  63. /// Emits the instruction to call the target <paramref name="method" />
  64. /// </summary>
  65. /// <param name="IL">The <see cref="ILGenerator" /> of the target method body.</param>
  66. /// <param name="method">The method that will be invoked.</param>
  67. protected override void EmitCall(ILGenerator IL, MethodInfo method)
  68. {
  69. var callInstruction = method.IsVirtual ? OpCodes.Callvirt : OpCodes.Call;
  70. IL.Emit(callInstruction, method);
  71. }
  72. }
  73. }