diff --git a/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs b/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs index 6f60cb1830..56675ec73f 100644 --- a/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs +++ b/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs @@ -2,7 +2,6 @@ using Castle.DynamicProxy; using Volo.Abp.DynamicProxy; using Volo.Abp.Threading; -using Volo.ExtensionMethods; namespace Volo.Abp.Castle.DynamicProxy { @@ -37,19 +36,18 @@ namespace Volo.Abp.Castle.DynamicProxy else { var interceptResult = _abpInterceptor.InterceptAsync(new CastleAbpMethodInvocationAdapter(invocation)); - - invocation.ReturnValue = InternalAsyncHelper.CallAwaitTaskWithPostActionAndFinallyAndGetResult( + var actualReturnValue = invocation.ReturnValue; + invocation.ReturnValue = InternalAsyncHelper.CallAwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult( 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! - () => interceptResult, - exception => { } + () => actualReturnValue, + () => interceptResult ); } } private void InterceptSyncMethod(IInvocation invocation) { - AsyncHelper.RunSync(() => _abpInterceptor.InterceptAsync(new CastleAbpMethodInvocationAdapter(invocation))); + _abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation)); } } } diff --git a/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs b/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs index acb2963ce8..7aa4731dfa 100644 --- a/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs +++ b/src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs @@ -30,34 +30,28 @@ namespace Volo.Abp.Castle.DynamicProxy Invocation = invocation; } - public Task ProceedAsync() - { - return Invocation.Method.IsAsync() - ? RunAsync() - : RunSync(); - } + public void Proceed() + { + Invocation.Proceed(); - private Task RunAsync() - { - Invocation.Proceed(); - return (Task) Invocation.ReturnValue; - } + if (Invocation.Method.IsAsync()) + { + AsyncHelper.RunSync(() => (Task) Invocation.ReturnValue); + } + } - private Task RunSync() + public Task ProceedAsync() { - Invocation.Proceed(); - - if (Method.ReturnType == typeof(void)) - { - return Task.CompletedTask; - } - else - { - return (Task) typeof(Task) - .GetMethod("FromResult", BindingFlags.Static | BindingFlags.Public) - .MakeGenericMethod(Method.ReturnType) - .Invoke(null, new object[] {Invocation.ReturnValue}); - } - } - } + Invocation.Proceed(); + + if (Invocation.Method.IsAsync()) + { + return (Task)Invocation.ReturnValue; + } + else + { + return Task.FromResult(Invocation.ReturnValue); + } + } + } } \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/DynamicProxy/AbpInterceptor.cs b/src/Volo.Abp/Volo/Abp/DynamicProxy/AbpInterceptor.cs new file mode 100644 index 0000000000..8874beafcf --- /dev/null +++ b/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; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpInterceptor.cs b/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpInterceptor.cs index d6acec1151..c03d17c272 100644 --- a/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpInterceptor.cs +++ b/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpInterceptor.cs @@ -2,8 +2,11 @@ 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); - } + } } diff --git a/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpMethodInvocation.cs b/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpMethodInvocation.cs index 0f95b83d13..92bd440363 100644 --- a/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpMethodInvocation.cs +++ b/src/Volo.Abp/Volo/Abp/DynamicProxy/IAbpMethodInvocation.cs @@ -16,6 +16,8 @@ namespace Volo.Abp.DynamicProxy object ReturnValue { get; set; } - Task ProceedAsync(); + void Proceed(); + + Task ProceedAsync(); } } \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/Threading/InternalAsyncHelper.cs b/src/Volo.Abp/Volo/Abp/Threading/InternalAsyncHelper.cs index 38b8cd2f0e..9972e59d3d 100644 --- a/src/Volo.Abp/Volo/Abp/Threading/InternalAsyncHelper.cs +++ b/src/Volo.Abp/Volo/Abp/Threading/InternalAsyncHelper.cs @@ -1,181 +1,193 @@ using System; using System.Reflection; using System.Threading.Tasks; +using JetBrains.Annotations; namespace Volo.Abp.Threading { - public static class InternalAsyncHelper //TODO: Rename since it's not internal anymore! - { - public static async Task AwaitTaskWithFinally(Task actualReturnValue, Action finalAction) - { - Exception exception = null; - - try - { - await actualReturnValue; - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - finalAction(exception); - } - } - - public static async Task AwaitTaskWithPostActionAndFinally(Task actualReturnValue, Func postAction, Action finalAction) - { - Exception exception = null; - - try - { - await actualReturnValue; - await postAction(); - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - finalAction(exception); - } - } - - public static async Task AwaitTaskWithPreActionAndPostActionAndFinally(Func actualReturnValue, Func preAction = null, Func postAction = null, Action finalAction = null) - { - Exception exception = null; - - try - { - if (preAction != null) - { - await preAction(); - } - - await actualReturnValue(); - - if (postAction != null) - { - await postAction(); - } - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - if (finalAction != null) - { - finalAction(exception); - } - } - } - - public static async Task AwaitTaskWithFinallyAndGetResult(Task actualReturnValue, Action finalAction) - { - Exception exception = null; - - try - { - return await actualReturnValue; - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - finalAction(exception); - } - } - - public static object CallAwaitTaskWithFinallyAndGetResult(Type taskReturnType, object actualReturnValue, Action finalAction) - { - return typeof(InternalAsyncHelper) - .GetTypeInfo() - .GetMethod("AwaitTaskWithFinallyAndGetResult", BindingFlags.Public | BindingFlags.Static) - .MakeGenericMethod(taskReturnType) - .Invoke(null, new object[] { actualReturnValue, finalAction }); - } - - public static async Task AwaitTaskWithPostActionAndFinallyAndGetResult(Task actualReturnValue, Func postAction, Action finalAction) - { - Exception exception = null; - - try - { - var result = await actualReturnValue; - await postAction(); - return result; - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - finalAction(exception); - } - } - - public static object CallAwaitTaskWithPostActionAndFinallyAndGetResult(Type taskReturnType, object actualReturnValue, Func action, Action finalAction) - { - return typeof (InternalAsyncHelper) - .GetTypeInfo() - .GetMethod("AwaitTaskWithPostActionAndFinallyAndGetResult", BindingFlags.Public | BindingFlags.Static) - .MakeGenericMethod(taskReturnType) - .Invoke(null, new object[] { actualReturnValue, action, finalAction }); - } - - public static async Task AwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult(Func> actualReturnValue, Func preAction = null, Func postAction = null, Action finalAction = null) - { - Exception exception = null; - - try - { - if (preAction != null) - { - await preAction(); - } - - var result = await actualReturnValue(); - - if (postAction != null) - { - await postAction(); - } - - return result; - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - if (finalAction != null) - { - finalAction(exception); - } - } - } - - public static object CallAwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult(Type taskReturnType, Func actualReturnValue, Func preAction = null, Func postAction = null, Action finalAction = null) - { - return typeof(InternalAsyncHelper) - .GetTypeInfo() - .GetMethod("AwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult", BindingFlags.Public | BindingFlags.Static) - .MakeGenericMethod(taskReturnType) - .Invoke(null, new object[] { actualReturnValue, preAction, postAction, finalAction }); - } - } + //TODO: Rename since it's not internal anymore! + //TODO: Cache GetMethod reflection! + public static class InternalAsyncHelper + { + public static async Task AwaitTaskWithFinally(Task actualReturnValue, Action finalAction) + { + Exception exception = null; + + try + { + await actualReturnValue; + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + finalAction(exception); + } + } + + public static async Task AwaitTaskWithPostActionAndFinally(Task actualReturnValue, Func postAction, Action finalAction) + { + Exception exception = null; + + try + { + await actualReturnValue; + await postAction(); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + finalAction(exception); + } + } + + public static async Task AwaitTaskWithPreActionAndPostActionAndFinally(Func actualReturnValue, Func preAction = null, Func postAction = null, Action finalAction = null) + { + Exception exception = null; + + try + { + if (preAction != null) + { + await preAction(); + } + + await actualReturnValue(); + + if (postAction != null) + { + await postAction(); + } + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + if (finalAction != null) + { + finalAction(exception); + } + } + } + + public static async Task AwaitTaskWithFinallyAndGetResult(Task actualReturnValue, Action finalAction) + { + Exception exception = null; + + try + { + return await actualReturnValue; + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + finalAction(exception); + } + } + + public static object CallAwaitTaskWithFinallyAndGetResult(Type taskReturnType, object actualReturnValue, Action finalAction) + { + return typeof(InternalAsyncHelper) + .GetTypeInfo() + .GetMethod("AwaitTaskWithFinallyAndGetResult", BindingFlags.Public | BindingFlags.Static) + .MakeGenericMethod(taskReturnType) + .Invoke(null, new object[] { actualReturnValue, finalAction }); + } + + public static async Task AwaitTaskWithPostActionAndFinallyAndGetResult(Task actualReturnValue, Func postAction, Action finalAction) + { + Exception exception = null; + + try + { + var result = await actualReturnValue; + await postAction(); + return result; + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + finalAction(exception); + } + } + + public static object CallAwaitTaskWithPostActionAndFinallyAndGetResult(Type taskReturnType, object actualReturnValue, Func action, Action finalAction) + { + return typeof(InternalAsyncHelper) + .GetTypeInfo() + .GetMethod("AwaitTaskWithPostActionAndFinallyAndGetResult", BindingFlags.Public | BindingFlags.Static) + .MakeGenericMethod(taskReturnType) + .Invoke(null, new object[] { actualReturnValue, action, finalAction }); + } + + public static async Task AwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult(Func> actualReturnValue, Func preAction = null, Func postAction = null, Action finalAction = null) + { + Exception exception = null; + + try + { + if (preAction != null) + { + await preAction(); + } + + var result = await actualReturnValue(); + + if (postAction != null) + { + await postAction(); + } + + return result; + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + finalAction?.Invoke(exception); + } + } + + public static object CallAwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult(Type taskReturnType, Func actualReturnValue, Func preAction = null, Func postAction = null, Action finalAction = null) + { + var returnFunc = typeof(InternalAsyncHelper) + .GetTypeInfo() + .GetMethod("ConvertFuncOfObjectToFuncOfTask", BindingFlags.NonPublic | BindingFlags.Static) + .MakeGenericMethod(taskReturnType) + .Invoke(null, new object[] {actualReturnValue}); + + return typeof(InternalAsyncHelper) + .GetTypeInfo() + .GetMethod("AwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult", BindingFlags.Public | BindingFlags.Static) + .MakeGenericMethod(taskReturnType) + .Invoke(null, new object[] { returnFunc, preAction, postAction, finalAction }); + } + + [UsedImplicitly] + private static Func> ConvertFuncOfObjectToFuncOfTask(Func actualReturnValue) + { + return () => (Task)actualReturnValue(); + } + } } \ No newline at end of file diff --git a/src/Volo.Abp/Volo/Abp/Uow/UnitOfWorkInterceptor.cs b/src/Volo.Abp/Volo/Abp/Uow/UnitOfWorkInterceptor.cs index 396ba05681..b486d84e09 100644 --- a/src/Volo.Abp/Volo/Abp/Uow/UnitOfWorkInterceptor.cs +++ b/src/Volo.Abp/Volo/Abp/Uow/UnitOfWorkInterceptor.cs @@ -4,7 +4,7 @@ using Volo.DependencyInjection; namespace Volo.Abp.Uow { - public class UnitOfWorkInterceptor : IAbpInterceptor, ITransientDependency + public class UnitOfWorkInterceptor : AbpInterceptor, ITransientDependency { private readonly IUnitOfWorkManager _unitOfWorkManager; @@ -13,7 +13,18 @@ namespace Volo.Abp.Uow _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! diff --git a/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/Interception/Autofac_Interception_Test.cs b/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/Interception/Autofac_Interception_Test.cs index 7c0ce926d3..9c891562ce 100644 --- a/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/Interception/Autofac_Interception_Test.cs +++ b/test/Volo.Abp.Autofac.Tests/Volo/Abp/Autofac/Interception/Autofac_Interception_Test.cs @@ -1,14 +1,13 @@ using System; -using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; -using Shouldly; using Volo.Abp.Castle.DynamicProxy; -using Xunit; namespace Volo.Abp.Autofac.Interception { public class Autofac_Interception_Test : CastleInterceptionTestBase { + //TODO: Sımplify using autofac in tests! + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) { options.UseAutofac(); @@ -18,95 +17,5 @@ namespace Volo.Abp.Autofac.Interception { return services.BuildAutofacServiceProvider(); } - - [Fact] - public async Task Should_Intercept_Async_Method_Without_Return_Value() - { - //Arrange - - var target = ServiceProvider.GetService(); - - //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(); - - //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(); - - //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(); - - //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"); - } - } + } } diff --git a/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/AbpCastleCoreTestModule.cs b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/AbpCastleCoreTestModule.cs index 94d0a4785a..c47a138f5b 100644 --- a/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/AbpCastleCoreTestModule.cs +++ b/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! if (typeof(SimpleInterceptionTargetClass) == registration.ImplementationType) { - registration.Interceptors.Add(); - registration.Interceptors.Add(); + registration.Interceptors.Add(); + registration.Interceptors.Add(); + registration.Interceptors.Add(); } } } diff --git a/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/CastleInterceptionTestBase.cs b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/CastleInterceptionTestBase.cs index 6c81a2e0c0..cccb5a8b67 100644 --- a/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/CastleInterceptionTestBase.cs +++ b/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 : AbpIntegratedTest where TStartupModule : IAbpModule { + [Fact] + public async Task Should_Intercept_Async_Method_Without_Return_Value() + { + //Arrange - } + var target = ServiceProvider.GetService(); + + //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(); + + //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(); + + //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(); + + //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"); + } + } } \ No newline at end of file diff --git a/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleAsyncInterceptor.cs b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleAsyncInterceptor.cs new file mode 100644 index 0000000000..c1ee13b496 --- /dev/null +++ b/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); + } + } +} \ No newline at end of file diff --git a/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleAsyncInterceptor2.cs b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleAsyncInterceptor2.cs new file mode 100644 index 0000000000..9a1ce837dd --- /dev/null +++ b/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 + { + + } +} \ No newline at end of file diff --git a/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleInterceptor.cs b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleInterceptor.cs deleted file mode 100644 index 3b6048d2d9..0000000000 --- a/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleInterceptor.cs +++ /dev/null @@ -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); - } - } -} \ No newline at end of file diff --git a/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleSyncInterceptor.cs b/test/Volo.Abp.Castle.Core.Tests/Volo/Abp/Castle/DynamicProxy/SimpleSyncInterceptor.cs new file mode 100644 index 0000000000..0c9a1abe3c --- /dev/null +++ b/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"); + } + } +} \ No newline at end of file