|
|
|
@ -1,4 +1,5 @@ |
|
|
|
using System.Threading.Tasks; |
|
|
|
using System.Reflection; |
|
|
|
using System.Threading.Tasks; |
|
|
|
using Castle.DynamicProxy; |
|
|
|
using Volo.Abp.DynamicProxy; |
|
|
|
using Volo.Abp.Threading; |
|
|
|
@ -8,6 +9,20 @@ namespace Volo.Abp.Castle.DynamicProxy |
|
|
|
public class CastleAbpInterceptorAdapter<TInterceptor> : IInterceptor |
|
|
|
where TInterceptor : IAbpInterceptor |
|
|
|
{ |
|
|
|
private static readonly MethodInfo MethodExecuteWithoutReturnValueAsync = |
|
|
|
typeof(CastleAbpInterceptorAdapter<TInterceptor>) |
|
|
|
.GetMethod( |
|
|
|
nameof(ExecuteWithoutReturnValueAsync), |
|
|
|
BindingFlags.NonPublic | BindingFlags.Instance |
|
|
|
); |
|
|
|
|
|
|
|
private static readonly MethodInfo MethodExecuteWithReturnValueAsync = |
|
|
|
typeof(CastleAbpInterceptorAdapter<TInterceptor>) |
|
|
|
.GetMethod( |
|
|
|
nameof(ExecuteWithReturnValueAsync), |
|
|
|
BindingFlags.NonPublic | BindingFlags.Instance |
|
|
|
); |
|
|
|
|
|
|
|
private readonly TInterceptor _abpInterceptor; |
|
|
|
|
|
|
|
public CastleAbpInterceptorAdapter(TInterceptor abpInterceptor) |
|
|
|
@ -17,39 +32,58 @@ namespace Volo.Abp.Castle.DynamicProxy |
|
|
|
|
|
|
|
public void Intercept(IInvocation invocation) |
|
|
|
{ |
|
|
|
var proceedInfo = invocation.CaptureProceedInfo(); |
|
|
|
|
|
|
|
var method = invocation.MethodInvocationTarget ?? invocation.Method; |
|
|
|
|
|
|
|
if (method.IsAsync()) |
|
|
|
{ |
|
|
|
InterceptAsyncMethod(invocation); |
|
|
|
InterceptAsyncMethod(invocation, proceedInfo); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
InterceptSyncMethod(invocation); |
|
|
|
InterceptSyncMethod(invocation, proceedInfo); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void InterceptAsyncMethod(IInvocation invocation) |
|
|
|
private void InterceptSyncMethod(IInvocation invocation, IInvocationProceedInfo proceedInfo) |
|
|
|
{ |
|
|
|
_abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation, proceedInfo)); |
|
|
|
} |
|
|
|
|
|
|
|
private void InterceptAsyncMethod(IInvocation invocation, IInvocationProceedInfo proceedInfo) |
|
|
|
{ |
|
|
|
if (invocation.Method.ReturnType == typeof(Task)) |
|
|
|
{ |
|
|
|
invocation.ReturnValue = _abpInterceptor.InterceptAsync(new CastleAbpMethodInvocationAdapter(invocation)); |
|
|
|
invocation.ReturnValue = MethodExecuteWithoutReturnValueAsync |
|
|
|
.Invoke(this, new object[] { invocation, proceedInfo }); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
var interceptResult = _abpInterceptor.InterceptAsync(new CastleAbpMethodInvocationAdapter(invocation)); |
|
|
|
var actualReturnValue = invocation.ReturnValue; |
|
|
|
invocation.ReturnValue = InternalAsyncHelper.CallAwaitTaskWithPreActionAndPostActionAndFinallyAndGetResult( |
|
|
|
invocation.Method.ReturnType.GenericTypeArguments[0], |
|
|
|
() => actualReturnValue, |
|
|
|
() => interceptResult |
|
|
|
); |
|
|
|
invocation.ReturnValue = MethodExecuteWithReturnValueAsync |
|
|
|
.MakeGenericMethod(invocation.Method.ReturnType.GenericTypeArguments[0]) |
|
|
|
.Invoke(this, new object[] {invocation, proceedInfo}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void InterceptSyncMethod(IInvocation invocation) |
|
|
|
private async Task ExecuteWithoutReturnValueAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo) |
|
|
|
{ |
|
|
|
_abpInterceptor.Intercept(new CastleAbpMethodInvocationAdapter(invocation)); |
|
|
|
await Task.Yield(); |
|
|
|
|
|
|
|
await _abpInterceptor.InterceptAsync( |
|
|
|
new CastleAbpMethodInvocationAdapter(invocation, proceedInfo) |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
private async Task<T> ExecuteWithReturnValueAsync<T>(IInvocation invocation, IInvocationProceedInfo proceedInfo) |
|
|
|
{ |
|
|
|
await Task.Yield(); |
|
|
|
|
|
|
|
await _abpInterceptor.InterceptAsync( |
|
|
|
new CastleAbpMethodInvocationAdapter(invocation, proceedInfo) |
|
|
|
); |
|
|
|
|
|
|
|
return await (Task<T>)invocation.ReturnValue; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|