Browse Source

Improved interception.

pull/96/head
Halil İbrahim Kalkan 10 years ago
parent
commit
343a9b38af
  1. 12
      src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs
  2. 48
      src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs
  3. 15
      src/Volo.Abp/Volo/Abp/DynamicProxy/AbpInterceptor.cs
  4. 7
      src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpInterceptor.cs
  5. 4
      src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpMethodInvocation.cs
  6. 360
      src/Volo.Abp/Volo/Abp/Threading/InternalAsyncHelper.cs
  7. 15
      src/Volo.Abp/Volo/Abp/Uow/UnitOfWorkInterceptor.cs
  8. 97
      test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/Interception/Autofac_Interception_Test.cs
  9. 5
      test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/AbpCastleCoreTestModule.cs
  10. 97
      test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/CastleInterceptionTestBase.cs
  11. 26
      test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleAsyncInterceptor.cs
  12. 7
      test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleAsyncInterceptor2.cs
  13. 31
      test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleInterceptor.cs
  14. 16
      test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleSyncInterceptor.cs

12
src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs

@ -2,7 +2,6 @@
using Castle.DynamicProxy; using Castle.DynamicProxy;
using Volo.Abp.DynamicProxy; using Volo.Abp.DynamicProxy;
using Volo.Abp.Threading; using Volo.Abp.Threading;
using Volo.ExtensionMethods;
namespace Volo.Abp.Castle.DynamicProxy namespace Volo.Abp.Castle.DynamicProxy
{ {
@ -37,19 +36,18 @@ namespace Volo.Abp.Castle.DynamicProxy
else else
{ {
var interceptResult = _abpInterceptor.InterceptAsync(new CastleAbpMethodInvocationAdapter(invocation)); var interceptResult = _abpInterceptor.InterceptAsync(new CastleAbpMethodInvocationAdapter(invocation));
var actualReturnValue = invocation.ReturnValue;
invocation.ReturnValue = InternalAsyncHelper.CallAwaitTaskWithPostActionAndFinallyAndGetResult( invocation.ReturnValue = InternalAsyncHelper.CallAwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult(
invocation.Method.ReturnType.GenericTypeArguments[0], invocation.Method.ReturnType.GenericTypeArguments[0],
invocation.ReturnValue, //TODO: Can not change return value in that case !!! Create an interceptor that changes return value, for test purposes! () => actualReturnValue,
() => interceptResult, () => interceptResult
exception => { }
); );
} }
} }
private void InterceptSyncMethod(IInvocation invocation) private void InterceptSyncMethod(IInvocation invocation)
{ {
AsyncHelper.RunSync(() => _abpInterceptor.InterceptAsync(new CastleAbpMethodInvocationAdapter(invocation))); _abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation));
} }
} }
} }

48
src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs

@ -30,34 +30,28 @@ namespace Volo.Abp.Castle.DynamicProxy
Invocation = invocation; Invocation = invocation;
} }
public Task ProceedAsync() public void Proceed()
{ {
return Invocation.Method.IsAsync() Invocation.Proceed();
? RunAsync()
: RunSync();
}
private Task RunAsync() if (Invocation.Method.IsAsync())
{ {
Invocation.Proceed(); AsyncHelper.RunSync(() => (Task) Invocation.ReturnValue);
return (Task) Invocation.ReturnValue; }
} }
private Task RunSync() public Task ProceedAsync()
{ {
Invocation.Proceed(); Invocation.Proceed();
if (Method.ReturnType == typeof(void)) if (Invocation.Method.IsAsync())
{ {
return Task.CompletedTask; return (Task)Invocation.ReturnValue;
} }
else else
{ {
return (Task) typeof(Task) return Task.FromResult(Invocation.ReturnValue);
.GetMethod("FromResult", BindingFlags.Static | BindingFlags.Public) }
.MakeGenericMethod(Method.ReturnType) }
.Invoke(null, new object[] {Invocation.ReturnValue}); }
}
}
}
} }

15
src/Volo.Abp/Volo/Abp/DynamicProxy/AbpInterceptor.cs

@ -0,0 +1,15 @@
using System.Threading.Tasks;
namespace Volo.Abp.DynamicProxy
{
public abstract class AbpInterceptor : IAbpInterceptor
{
public abstract void Intercept(IAbpMethodInvocation invocation);
public virtual Task InterceptAsync(IAbpMethodInvocation invocation)
{
Intercept(invocation);
return Task.CompletedTask;
}
}
}

7
src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpInterceptor.cs

@ -2,8 +2,11 @@
namespace Volo.Abp.DynamicProxy namespace Volo.Abp.DynamicProxy
{ {
public interface IAbpInterceptor //TODO: Create also Intercept() for sync method interception! Create AbpInterceptor for simpler usage!
public interface IAbpInterceptor
{ {
void Intercept(IAbpMethodInvocation invocation);
Task InterceptAsync(IAbpMethodInvocation invocation); Task InterceptAsync(IAbpMethodInvocation invocation);
} }
} }

4
src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpMethodInvocation.cs

@ -16,6 +16,8 @@ namespace Volo.Abp.DynamicProxy
object ReturnValue { get; set; } object ReturnValue { get; set; }
Task ProceedAsync(); void Proceed();
Task ProceedAsync();
} }
} }

360
src/Volo.Abp/Volo/Abp/Threading/InternalAsyncHelper.cs

@ -1,181 +1,193 @@
using System; using System;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Volo.Abp.Threading namespace Volo.Abp.Threading
{ {
public static class InternalAsyncHelper //TODO: Rename since it's not internal anymore! //TODO: Rename since it's not internal anymore!
{ //TODO: Cache GetMethod reflection!
public static async Task AwaitTaskWithFinally(Task actualReturnValue, Action<Exception> finalAction) public static class InternalAsyncHelper
{ {
Exception exception = null; public static async Task AwaitTaskWithFinally(Task actualReturnValue, Action<Exception> finalAction)
{
try Exception exception = null;
{
await actualReturnValue; try
} {
catch (Exception ex) await actualReturnValue;
{ }
exception = ex; catch (Exception ex)
throw; {
} exception = ex;
finally throw;
{ }
finalAction(exception); finally
} {
} finalAction(exception);
}
public static async Task AwaitTaskWithPostActionAndFinally(Task actualReturnValue, Func<Task> postAction, Action<Exception> finalAction) }
{
Exception exception = null; public static async Task AwaitTaskWithPostActionAndFinally(Task actualReturnValue, Func<Task> postAction, Action<Exception> finalAction)
{
try Exception exception = null;
{
await actualReturnValue; try
await postAction(); {
} await actualReturnValue;
catch (Exception ex) await postAction();
{ }
exception = ex; catch (Exception ex)
throw; {
} exception = ex;
finally throw;
{ }
finalAction(exception); finally
} {
} finalAction(exception);
}
public static async Task AwaitTaskWithPreActionAndPostActionAndFinally(Func<Task> actualReturnValue, Func<Task> preAction = null, Func<Task> postAction = null, Action<Exception> finalAction = null) }
{
Exception exception = null; public static async Task AwaitTaskWithPreActionAndPostActionAndFinally(Func<Task> actualReturnValue, Func<Task> preAction = null, Func<Task> postAction = null, Action<Exception> finalAction = null)
{
try Exception exception = null;
{
if (preAction != null) try
{ {
await preAction(); if (preAction != null)
} {
await preAction();
await actualReturnValue(); }
if (postAction != null) await actualReturnValue();
{
await postAction(); if (postAction != null)
} {
} await postAction();
catch (Exception ex) }
{ }
exception = ex; catch (Exception ex)
throw; {
} exception = ex;
finally throw;
{ }
if (finalAction != null) finally
{ {
finalAction(exception); if (finalAction != null)
} {
} finalAction(exception);
} }
}
public static async Task<T> AwaitTaskWithFinallyAndGetResult<T>(Task<T> actualReturnValue, Action<Exception> finalAction) }
{
Exception exception = null; public static async Task<T> AwaitTaskWithFinallyAndGetResult<T>(Task<T> actualReturnValue, Action<Exception> finalAction)
{
try Exception exception = null;
{
return await actualReturnValue; try
} {
catch (Exception ex) return await actualReturnValue;
{ }
exception = ex; catch (Exception ex)
throw; {
} exception = ex;
finally throw;
{ }
finalAction(exception); finally
} {
} finalAction(exception);
}
public static object CallAwaitTaskWithFinallyAndGetResult(Type taskReturnType, object actualReturnValue, Action<Exception> finalAction) }
{
return typeof(InternalAsyncHelper) public static object CallAwaitTaskWithFinallyAndGetResult(Type taskReturnType, object actualReturnValue, Action<Exception> finalAction)
.GetTypeInfo() {
.GetMethod("AwaitTaskWithFinallyAndGetResult", BindingFlags.Public | BindingFlags.Static) return typeof(InternalAsyncHelper)
.MakeGenericMethod(taskReturnType) .GetTypeInfo()
.Invoke(null, new object[] { actualReturnValue, finalAction }); .GetMethod("AwaitTaskWithFinallyAndGetResult", BindingFlags.Public | BindingFlags.Static)
} .MakeGenericMethod(taskReturnType)
.Invoke(null, new object[] { actualReturnValue, finalAction });
public static async Task<T> AwaitTaskWithPostActionAndFinallyAndGetResult<T>(Task<T> actualReturnValue, Func<Task> postAction, Action<Exception> finalAction) }
{
Exception exception = null; public static async Task<T> AwaitTaskWithPostActionAndFinallyAndGetResult<T>(Task<T> actualReturnValue, Func<Task> postAction, Action<Exception> finalAction)
{
try Exception exception = null;
{
var result = await actualReturnValue; try
await postAction(); {
return result; var result = await actualReturnValue;
} await postAction();
catch (Exception ex) return result;
{ }
exception = ex; catch (Exception ex)
throw; {
} exception = ex;
finally throw;
{ }
finalAction(exception); finally
} {
} finalAction(exception);
}
public static object CallAwaitTaskWithPostActionAndFinallyAndGetResult(Type taskReturnType, object actualReturnValue, Func<Task> action, Action<Exception> finalAction) }
{
return typeof (InternalAsyncHelper) public static object CallAwaitTaskWithPostActionAndFinallyAndGetResult(Type taskReturnType, object actualReturnValue, Func<Task> action, Action<Exception> finalAction)
.GetTypeInfo() {
.GetMethod("AwaitTaskWithPostActionAndFinallyAndGetResult", BindingFlags.Public | BindingFlags.Static) return typeof(InternalAsyncHelper)
.MakeGenericMethod(taskReturnType) .GetTypeInfo()
.Invoke(null, new object[] { actualReturnValue, action, finalAction }); .GetMethod("AwaitTaskWithPostActionAndFinallyAndGetResult", BindingFlags.Public | BindingFlags.Static)
} .MakeGenericMethod(taskReturnType)
.Invoke(null, new object[] { actualReturnValue, action, finalAction });
public static async Task<T> AwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult<T>(Func<Task<T>> actualReturnValue, Func<Task> preAction = null, Func<Task> postAction = null, Action<Exception> finalAction = null) }
{
Exception exception = null; public static async Task<T> AwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult<T>(Func<Task<T>> actualReturnValue, Func<Task> preAction = null, Func<Task> postAction = null, Action<Exception> finalAction = null)
{
try Exception exception = null;
{
if (preAction != null) try
{ {
await preAction(); if (preAction != null)
} {
await preAction();
var result = await actualReturnValue(); }
if (postAction != null) var result = await actualReturnValue();
{
await postAction(); if (postAction != null)
} {
await postAction();
return result; }
}
catch (Exception ex) return result;
{ }
exception = ex; catch (Exception ex)
throw; {
} exception = ex;
finally throw;
{ }
if (finalAction != null) finally
{ {
finalAction(exception); finalAction?.Invoke(exception);
} }
} }
}
public static object CallAwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult(Type taskReturnType, Func<object> actualReturnValue, Func<Task> preAction = null, Func<Task> postAction = null, Action<Exception> finalAction = null)
public static object CallAwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult(Type taskReturnType, Func<object> actualReturnValue, Func<Task> preAction = null, Func<Task> postAction = null, Action<Exception> finalAction = null) {
{ var returnFunc = typeof(InternalAsyncHelper)
return typeof(InternalAsyncHelper) .GetTypeInfo()
.GetTypeInfo() .GetMethod("ConvertFuncOfObjectToFuncOfTask", BindingFlags.NonPublic | BindingFlags.Static)
.GetMethod("AwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult", BindingFlags.Public | BindingFlags.Static) .MakeGenericMethod(taskReturnType)
.MakeGenericMethod(taskReturnType) .Invoke(null, new object[] {actualReturnValue});
.Invoke(null, new object[] { actualReturnValue, preAction, postAction, finalAction });
} return typeof(InternalAsyncHelper)
} .GetTypeInfo()
.GetMethod("AwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult", BindingFlags.Public | BindingFlags.Static)
.MakeGenericMethod(taskReturnType)
.Invoke(null, new object[] { returnFunc, preAction, postAction, finalAction });
}
[UsedImplicitly]
private static Func<Task<T>> ConvertFuncOfObjectToFuncOfTask<T>(Func<object> actualReturnValue)
{
return () => (Task<T>)actualReturnValue();
}
}
} }

15
src/Volo.Abp/Volo/Abp/Uow/UnitOfWorkInterceptor.cs

@ -4,7 +4,7 @@ using Volo.DependencyInjection;
namespace Volo.Abp.Uow namespace Volo.Abp.Uow
{ {
public class UnitOfWorkInterceptor : IAbpInterceptor, ITransientDependency public class UnitOfWorkInterceptor : AbpInterceptor, ITransientDependency
{ {
private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly IUnitOfWorkManager _unitOfWorkManager;
@ -13,7 +13,18 @@ namespace Volo.Abp.Uow
_unitOfWorkManager = unitOfWorkManager; _unitOfWorkManager = unitOfWorkManager;
} }
public async Task InterceptAsync(IAbpMethodInvocation invocation) public override void Intercept(IAbpMethodInvocation invocation)
{
//TODO: Check UOW attribute and other conditions!
using (var uow = _unitOfWorkManager.Begin())
{
invocation.Proceed();
uow.Complete();
}
}
public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{ {
//TODO: Check UOW attribute and other conditions! //TODO: Check UOW attribute and other conditions!

97
test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/Interception/Autofac_Interception_Test.cs

@ -1,14 +1,13 @@
using System; using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.Castle.DynamicProxy; using Volo.Abp.Castle.DynamicProxy;
using Xunit;
namespace Volo.Abp.Autofac.Interception namespace Volo.Abp.Autofac.Interception
{ {
public class Autofac_Interception_Test : CastleInterceptionTestBase<AutofacTestModule> public class Autofac_Interception_Test : CastleInterceptionTestBase<AutofacTestModule>
{ {
//TODO: Sımplify using autofac in tests!
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
{ {
options.UseAutofac(); options.UseAutofac();
@ -18,95 +17,5 @@ namespace Volo.Abp.Autofac.Interception
{ {
return services.BuildAutofacServiceProvider(); return services.BuildAutofacServiceProvider();
} }
}
[Fact]
public async Task Should_Intercept_Async_Method_Without_Return_Value()
{
//Arrange
var target = ServiceProvider.GetService<SimpleInterceptionTargetClass>();
//Act
await target.DoItAsync();
//Assert
target.Logs.Count.ShouldBe(7);
target.Logs[0].ShouldBe("SimpleInterceptor_BeforeInvocation");
target.Logs[1].ShouldBe("SimpleInterceptor2_BeforeInvocation");
target.Logs[2].ShouldBe("EnterDoItAsync");
target.Logs[3].ShouldBe("MiddleDoItAsync");
target.Logs[4].ShouldBe("ExitDoItAsync");
target.Logs[5].ShouldBe("SimpleInterceptor2_AfterInvocation");
target.Logs[6].ShouldBe("SimpleInterceptor_AfterInvocation");
}
[Fact]
public async Task Should_Intercept_Async_Method_With_Return_Value()
{
//Arrange
var target = ServiceProvider.GetService<SimpleInterceptionTargetClass>();
//Act
var result = await target.GetValueAsync();
//Assert
result.ShouldBe(42);
target.Logs.Count.ShouldBe(7);
target.Logs[0].ShouldBe("SimpleInterceptor_BeforeInvocation");
target.Logs[1].ShouldBe("SimpleInterceptor2_BeforeInvocation");
target.Logs[2].ShouldBe("EnterGetValueAsync");
target.Logs[3].ShouldBe("MiddleGetValueAsync");
target.Logs[4].ShouldBe("ExitGetValueAsync");
target.Logs[5].ShouldBe("SimpleInterceptor2_AfterInvocation");
target.Logs[6].ShouldBe("SimpleInterceptor_AfterInvocation");
}
[Fact]
public void Should_Intercept_Sync_Method_Without_Return_Value()
{
//Arrange
var target = ServiceProvider.GetService<SimpleInterceptionTargetClass>();
//Act
target.DoIt();
//Assert
target.Logs.Count.ShouldBe(5);
target.Logs[0].ShouldBe("SimpleInterceptor_BeforeInvocation");
target.Logs[1].ShouldBe("SimpleInterceptor2_BeforeInvocation");
target.Logs[2].ShouldBe("ExecutingDoIt");
target.Logs[3].ShouldBe("SimpleInterceptor2_AfterInvocation");
target.Logs[4].ShouldBe("SimpleInterceptor_AfterInvocation");
}
[Fact]
public void Should_Intercept_Sync_Method_With_Return_Value()
{
//Arrange
var target = ServiceProvider.GetService<SimpleInterceptionTargetClass>();
//Act
var result = target.GetValue();
//Assert
result.ShouldBe(42);
target.Logs.Count.ShouldBe(5);
target.Logs[0].ShouldBe("SimpleInterceptor_BeforeInvocation");
target.Logs[1].ShouldBe("SimpleInterceptor2_BeforeInvocation");
target.Logs[2].ShouldBe("ExecutingGetValue");
target.Logs[3].ShouldBe("SimpleInterceptor2_AfterInvocation");
target.Logs[4].ShouldBe("SimpleInterceptor_AfterInvocation");
}
}
} }

5
test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/AbpCastleCoreTestModule.cs

@ -22,8 +22,9 @@ namespace Volo.Abp.Castle
//TODO: Create an attribute to add interceptors! //TODO: Create an attribute to add interceptors!
if (typeof(SimpleInterceptionTargetClass) == registration.ImplementationType) if (typeof(SimpleInterceptionTargetClass) == registration.ImplementationType)
{ {
registration.Interceptors.Add<SimpleInterceptor>(); registration.Interceptors.Add<SimpleAsyncInterceptor>();
registration.Interceptors.Add<SimpleInterceptor2>(); registration.Interceptors.Add<SimpleSyncInterceptor>();
registration.Interceptors.Add<SimpleAsyncInterceptor2>();
} }
} }
} }

97
test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/CastleInterceptionTestBase.cs

@ -11,6 +11,101 @@ namespace Volo.Abp.Castle.DynamicProxy
public abstract class CastleInterceptionTestBase<TStartupModule> : AbpIntegratedTest<TStartupModule> public abstract class CastleInterceptionTestBase<TStartupModule> : AbpIntegratedTest<TStartupModule>
where TStartupModule : IAbpModule where TStartupModule : IAbpModule
{ {
[Fact]
public async Task Should_Intercept_Async_Method_Without_Return_Value()
{
//Arrange
} var target = ServiceProvider.GetService<SimpleInterceptionTargetClass>();
//Act
await target.DoItAsync();
//Assert
target.Logs.Count.ShouldBe(9);
target.Logs[0].ShouldBe("SimpleAsyncInterceptor_InterceptAsync_BeforeInvocation");
target.Logs[1].ShouldBe("SimpleSyncInterceptor_Intercept_BeforeInvocation");
target.Logs[2].ShouldBe("SimpleAsyncInterceptor2_InterceptAsync_BeforeInvocation");
target.Logs[3].ShouldBe("EnterDoItAsync");
target.Logs[4].ShouldBe("MiddleDoItAsync");
target.Logs[5].ShouldBe("ExitDoItAsync");
target.Logs[6].ShouldBe("SimpleAsyncInterceptor2_InterceptAsync_AfterInvocation");
target.Logs[7].ShouldBe("SimpleSyncInterceptor_Intercept_AfterInvocation");
target.Logs[8].ShouldBe("SimpleAsyncInterceptor_InterceptAsync_AfterInvocation");
}
[Fact]
public async Task Should_Intercept_Async_Method_With_Return_Value()
{
//Arrange
var target = ServiceProvider.GetService<SimpleInterceptionTargetClass>();
//Act
var result = await target.GetValueAsync();
//Assert
result.ShouldBe(42);
target.Logs.Count.ShouldBe(9);
target.Logs[0].ShouldBe("SimpleAsyncInterceptor_InterceptAsync_BeforeInvocation");
target.Logs[1].ShouldBe("SimpleSyncInterceptor_Intercept_BeforeInvocation");
target.Logs[2].ShouldBe("SimpleAsyncInterceptor2_InterceptAsync_BeforeInvocation");
target.Logs[3].ShouldBe("EnterGetValueAsync");
target.Logs[4].ShouldBe("MiddleGetValueAsync");
target.Logs[5].ShouldBe("ExitGetValueAsync");
target.Logs[6].ShouldBe("SimpleAsyncInterceptor2_InterceptAsync_AfterInvocation");
target.Logs[7].ShouldBe("SimpleSyncInterceptor_Intercept_AfterInvocation");
target.Logs[8].ShouldBe("SimpleAsyncInterceptor_InterceptAsync_AfterInvocation");
}
[Fact]
public void Should_Intercept_Sync_Method_Without_Return_Value()
{
//Arrange
var target = ServiceProvider.GetService<SimpleInterceptionTargetClass>();
//Act
target.DoIt();
//Assert
target.Logs.Count.ShouldBe(7);
target.Logs[0].ShouldBe("SimpleAsyncInterceptor_Intercept_BeforeInvocation");
target.Logs[1].ShouldBe("SimpleSyncInterceptor_Intercept_BeforeInvocation");
target.Logs[2].ShouldBe("SimpleAsyncInterceptor2_Intercept_BeforeInvocation");
target.Logs[3].ShouldBe("ExecutingDoIt");
target.Logs[4].ShouldBe("SimpleAsyncInterceptor2_Intercept_AfterInvocation");
target.Logs[5].ShouldBe("SimpleSyncInterceptor_Intercept_AfterInvocation");
target.Logs[6].ShouldBe("SimpleAsyncInterceptor_Intercept_AfterInvocation");
}
[Fact]
public void Should_Intercept_Sync_Method_With_Return_Value()
{
//Arrange
var target = ServiceProvider.GetService<SimpleInterceptionTargetClass>();
//Act
var result = target.GetValue();
//Assert
result.ShouldBe(42);
target.Logs.Count.ShouldBe(7);
target.Logs[0].ShouldBe("SimpleAsyncInterceptor_Intercept_BeforeInvocation");
target.Logs[1].ShouldBe("SimpleSyncInterceptor_Intercept_BeforeInvocation");
target.Logs[2].ShouldBe("SimpleAsyncInterceptor2_Intercept_BeforeInvocation");
target.Logs[3].ShouldBe("ExecutingGetValue");
target.Logs[4].ShouldBe("SimpleAsyncInterceptor2_Intercept_AfterInvocation");
target.Logs[5].ShouldBe("SimpleSyncInterceptor_Intercept_AfterInvocation");
target.Logs[6].ShouldBe("SimpleAsyncInterceptor_Intercept_AfterInvocation");
}
}
} }

26
test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleAsyncInterceptor.cs

@ -0,0 +1,26 @@
using System.Threading.Tasks;
using Volo.Abp.DynamicProxy;
using Volo.Abp.TestBase.Logging;
using Volo.DependencyInjection;
namespace Volo.Abp.Castle.DynamicProxy
{
public class SimpleAsyncInterceptor : AbpInterceptor, ITransientDependency
{
public override void Intercept(IAbpMethodInvocation invocation)
{
(invocation.TargetObject as ICanLogOnObject)?.Logs?.Add($"{GetType().Name}_Intercept_BeforeInvocation");
invocation.ProceedAsync();
(invocation.TargetObject as ICanLogOnObject)?.Logs?.Add($"{GetType().Name}_Intercept_AfterInvocation");
}
public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{
//await Task.Delay(5); CAN NOT USE await before method execution! This is a restriction of Castle DynamicProxy
(invocation.TargetObject as ICanLogOnObject)?.Logs?.Add($"{GetType().Name}_InterceptAsync_BeforeInvocation");
await invocation.ProceedAsync();
(invocation.TargetObject as ICanLogOnObject)?.Logs?.Add($"{GetType().Name}_InterceptAsync_AfterInvocation");
await Task.Delay(5);
}
}
}

7
test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleAsyncInterceptor2.cs

@ -0,0 +1,7 @@
namespace Volo.Abp.Castle.DynamicProxy
{
public class SimpleAsyncInterceptor2 : SimpleAsyncInterceptor
{
}
}

31
test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleInterceptor.cs

@ -1,31 +0,0 @@
using System.Threading.Tasks;
using Volo.Abp.DynamicProxy;
using Volo.Abp.TestBase.Logging;
using Volo.DependencyInjection;
namespace Volo.Abp.Castle.DynamicProxy
{
public class SimpleInterceptor : IAbpInterceptor, ITransientDependency
{
public async Task InterceptAsync(IAbpMethodInvocation invocation)
{
//await Task.Delay(5);
(invocation.TargetObject as ICanLogOnObject)?.Logs?.Add("SimpleInterceptor_BeforeInvocation");
await invocation.ProceedAsync();
(invocation.TargetObject as ICanLogOnObject)?.Logs?.Add("SimpleInterceptor_AfterInvocation");
await Task.Delay(5);
}
}
public class SimpleInterceptor2 : IAbpInterceptor, ITransientDependency
{
public async Task InterceptAsync(IAbpMethodInvocation invocation)
{
//await Task.Delay(5);
(invocation.TargetObject as ICanLogOnObject)?.Logs?.Add("SimpleInterceptor2_BeforeInvocation");
await invocation.ProceedAsync();
(invocation.TargetObject as ICanLogOnObject)?.Logs?.Add("SimpleInterceptor2_AfterInvocation");
await Task.Delay(5);
}
}
}

16
test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleSyncInterceptor.cs

@ -0,0 +1,16 @@
using Volo.Abp.DynamicProxy;
using Volo.Abp.TestBase.Logging;
using Volo.DependencyInjection;
namespace Volo.Abp.Castle.DynamicProxy
{
public class SimpleSyncInterceptor : AbpInterceptor, ITransientDependency
{
public override void Intercept(IAbpMethodInvocation invocation)
{
(invocation.TargetObject as ICanLogOnObject)?.Logs?.Add($"{GetType().Name}_Intercept_BeforeInvocation");
invocation.Proceed();
(invocation.TargetObject as ICanLogOnObject)?.Logs?.Add($"{GetType().Name}_Intercept_AfterInvocation");
}
}
}
Loading…
Cancel
Save