/src/UnitTests/AOP/ThirdPartyMethodCallInterceptionTests.cs

http://github.com/philiplaureano/LinFu · C# · 147 lines · 116 code · 30 blank · 1 comment · 9 complexity · 961efebe99a576160b485f4c47e11ef3 MD5 · raw file

  1. using System;
  2. using System.Linq;
  3. using System.Reflection;
  4. using LinFu.AOP.Cecil.Extensions;
  5. using LinFu.AOP.Interfaces;
  6. using LinFu.Reflection.Emit;
  7. using Mono.Cecil;
  8. using Xunit;
  9. using SampleLibrary.AOP;
  10. namespace LinFu.UnitTests.AOP
  11. {
  12. public class ThirdPartyMethodCallInterceptionTests : BaseTestFixture
  13. {
  14. protected override void Init()
  15. {
  16. }
  17. protected override void Term()
  18. {
  19. AroundInvokeMethodCallRegistry.Clear();
  20. }
  21. private Type GetModifiedTargetType()
  22. {
  23. return GetModifiedTargetType(Modify);
  24. }
  25. private Type GetModifiedTargetType(Action<string, TypeDefinition> modify)
  26. {
  27. var assembly = AssemblyDefinition.ReadAssembly("SampleLibrary.dll");
  28. var module = assembly.MainModule;
  29. // Intercept all calls to the System.Console.WriteLine method from the DoSomething method
  30. var typeName = "SampleClassWithThirdPartyMethodCall";
  31. var targetType = (from TypeDefinition t in module.Types
  32. where t.Name == typeName
  33. select t).First();
  34. modify(typeName, targetType);
  35. var modifiedAssembly = assembly.ToAssembly();
  36. return (from t in modifiedAssembly.GetTypes()
  37. where t.Name == typeName
  38. select t).First();
  39. }
  40. private void Modify(string typeName, TypeDefinition targetType)
  41. {
  42. targetType.InterceptMethodCalls(t => t.Name.Contains(typeName),
  43. m => m.DeclaringType.Name.Contains(typeName) && m.Name == "DoSomething",
  44. methodCall =>
  45. methodCall.DeclaringType.Name == "Console" && methodCall.Name == "WriteLine");
  46. }
  47. [Fact]
  48. public void ShouldCallInstanceAroundInvokeProvider()
  49. {
  50. var modifiedTargetType = GetModifiedTargetType();
  51. var instance = Activator.CreateInstance(modifiedTargetType);
  52. var aroundInvoke = new SampleAroundInvoke();
  53. var provider = new SampleAroundInvokeProvider(aroundInvoke);
  54. var modified = (IModifiableType) instance;
  55. modified.AroundMethodCallProvider = provider;
  56. var targetMethod = modifiedTargetType.GetMethod("DoSomething");
  57. Assert.NotNull(targetMethod);
  58. targetMethod.Invoke(instance, null);
  59. Assert.True(aroundInvoke.BeforeInvokeWasCalled);
  60. Assert.True(aroundInvoke.AfterInvokeWasCalled);
  61. }
  62. [Fact]
  63. public void ShouldCallStaticAroundInvokeProvider()
  64. {
  65. var modifiedTargetType = GetModifiedTargetType();
  66. var instance = Activator.CreateInstance(modifiedTargetType);
  67. var aroundInvoke = new SampleAroundInvoke();
  68. var provider = new SampleAroundInvokeProvider(aroundInvoke);
  69. AroundInvokeMethodCallRegistry.AddProvider(provider);
  70. var targetMethod = modifiedTargetType.GetMethod("DoSomething");
  71. Assert.NotNull(targetMethod);
  72. targetMethod.Invoke(instance, null);
  73. Assert.True(aroundInvoke.BeforeInvokeWasCalled);
  74. Assert.True(aroundInvoke.AfterInvokeWasCalled);
  75. }
  76. [Fact]
  77. public void ShouldImplementIMethodReplacementHostOnTargetType()
  78. {
  79. var modifiedTargetType = GetModifiedTargetType();
  80. var instance = Activator.CreateInstance(modifiedTargetType);
  81. Assert.NotNull(instance);
  82. Assert.True(instance is IMethodReplacementHost);
  83. var host = (IMethodReplacementHost) instance;
  84. var interceptor = new SampleMethodReplacement();
  85. host.MethodCallReplacementProvider = new SampleMethodReplacementProvider(interceptor);
  86. var targetMethod = modifiedTargetType.GetMethod("DoSomething");
  87. Assert.NotNull(targetMethod);
  88. try
  89. {
  90. targetMethod.Invoke(instance, null);
  91. }
  92. catch (TargetInvocationException ex)
  93. {
  94. var innerException = ex.InnerException;
  95. Console.WriteLine(ex.ToString());
  96. if (innerException != null)
  97. throw innerException;
  98. throw;
  99. }
  100. Assert.True(interceptor.HasBeenCalled);
  101. }
  102. [Fact]
  103. public void ShouldNotInterceptConstructorsWhenIntereptingAllMethodCalls()
  104. {
  105. var modifiedTargetType = GetModifiedTargetType((name, type) => type.InterceptAllMethodCalls());
  106. var instance = Activator.CreateInstance(modifiedTargetType);
  107. var aroundInvoke = new SampleAroundInvoke();
  108. var provider = new SampleAroundInvokeProvider(aroundInvoke);
  109. AroundInvokeMethodCallRegistry.AddProvider(provider);
  110. var targetMethod = modifiedTargetType.GetMethod("DoSomething");
  111. Assert.NotNull(targetMethod);
  112. targetMethod.Invoke(instance, null);
  113. Assert.True(aroundInvoke.BeforeInvokeWasCalled);
  114. Assert.True(aroundInvoke.AfterInvokeWasCalled);
  115. }
  116. }
  117. }