PageRenderTime 28ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/LinFu.AOP/Factories/AddInvocationInfoActionFactory.cs

http://github.com/philiplaureano/LinFu
C# | 57 lines | 35 code | 6 blank | 16 comment | 2 complexity | a7f7dc90d1de3298549e8a3591a81768 MD5 | raw file
  1. using System;
  2. using System.Linq;
  3. using LinFu.AOP.Cecil.Interfaces;
  4. using LinFu.AOP.Interfaces;
  5. using LinFu.IoC.Configuration;
  6. using LinFu.IoC.Interfaces;
  7. using LinFu.Reflection.Emit;
  8. using Mono.Cecil;
  9. using Mono.Cecil.Cil;
  10. namespace LinFu.AOP.Cecil.Factories
  11. {
  12. /// <summary>
  13. /// A factory instance that creates <see cref="Action{T}" /> delegates
  14. /// that emit the necessary <see cref="IInvocationInfo" /> information
  15. /// and store it in a local variable named '__invocationInfo___'.
  16. /// </summary>
  17. [Factory(typeof(Action<MethodDefinition>), ServiceName = "AddInvocationInfo")]
  18. public class AddInvocationInfoActionFactory : IFactory
  19. {
  20. /// <summary>
  21. /// Generates the <see cref="Action{T}" /> delegate that will emit
  22. /// the necessary <see cref="IInvocationInfo" /> information.
  23. /// </summary>
  24. /// <param name="request">The <see cref="IFactoryRequest" /> instance that describes the requested service type.</param>
  25. /// <returns>
  26. /// A delegate that can emit the necessary <see cref="IInvocationInfo" /> context that will allow other developers
  27. /// to infer information about the method currently being executed.
  28. /// </returns>
  29. public object CreateInstance(IFactoryRequest request)
  30. {
  31. var container = request.Container;
  32. Action<MethodDefinition> result =
  33. method =>
  34. {
  35. var body = method.Body;
  36. // Add the IInvocationInfo
  37. // instance only once
  38. var localAlreadyExists = (from VariableDefinition local in body.Variables
  39. where local.Name == "___invocationInfo___"
  40. select local).Count() > 0;
  41. if (localAlreadyExists)
  42. return;
  43. var variable = method.AddLocal<IInvocationInfo>();
  44. variable.Name = "___invocationInfo___";
  45. var emitInfo = (IEmitInvocationInfo) container.GetService(typeof(IEmitInvocationInfo));
  46. emitInfo.Emit(method, method, variable);
  47. };
  48. return result;
  49. }
  50. }
  51. }