mirror of https://github.com/abpframework/abp.git
11 changed files with 161 additions and 132 deletions
@ -0,0 +1,15 @@ |
|||||
|
using Castle.DynamicProxy; |
||||
|
using Volo.Abp.DynamicProxy; |
||||
|
|
||||
|
namespace Volo.Abp.Castle.DynamicProxy |
||||
|
{ |
||||
|
public class AbpAsyncDeterminationInterceptor<TInterceptor> : AsyncDeterminationInterceptor |
||||
|
where TInterceptor : IAbpInterceptor |
||||
|
{ |
||||
|
public AbpAsyncDeterminationInterceptor(TInterceptor abpInterceptor) |
||||
|
: base(new CastleAsyncAbpInterceptorAdapter<TInterceptor>(abpInterceptor)) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,73 +0,0 @@ |
|||||
using System.Reflection; |
|
||||
using System.Threading.Tasks; |
|
||||
using Castle.DynamicProxy; |
|
||||
using Volo.Abp.DynamicProxy; |
|
||||
using Volo.Abp.Threading; |
|
||||
|
|
||||
namespace Volo.Abp.Castle.DynamicProxy |
|
||||
{ |
|
||||
public class CastleAbpInterceptorAdapter<TInterceptor> : IInterceptor |
|
||||
where TInterceptor : IAbpInterceptor |
|
||||
{ |
|
||||
private static readonly MethodInfo MethodExecuteWithReturnValueAsync = |
|
||||
typeof(CastleAbpInterceptorAdapter<TInterceptor>) |
|
||||
.GetMethod( |
|
||||
nameof(ExecuteWithReturnValueAsync), |
|
||||
BindingFlags.NonPublic | BindingFlags.Instance |
|
||||
); |
|
||||
|
|
||||
private readonly TInterceptor _abpInterceptor; |
|
||||
|
|
||||
public CastleAbpInterceptorAdapter(TInterceptor abpInterceptor) |
|
||||
{ |
|
||||
_abpInterceptor = abpInterceptor; |
|
||||
} |
|
||||
|
|
||||
public void Intercept(IInvocation invocation) |
|
||||
{ |
|
||||
var proceedInfo = invocation.CaptureProceedInfo(); |
|
||||
|
|
||||
var method = invocation.MethodInvocationTarget ?? invocation.Method; |
|
||||
|
|
||||
if (!method.IsAsync()) |
|
||||
{ |
|
||||
proceedInfo.Invoke(); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
InterceptAsyncMethod(invocation, proceedInfo); |
|
||||
} |
|
||||
|
|
||||
private void InterceptAsyncMethod(IInvocation invocation, IInvocationProceedInfo proceedInfo) |
|
||||
{ |
|
||||
if (invocation.Method.ReturnType == typeof(Task)) |
|
||||
{ |
|
||||
invocation.ReturnValue = ExecuteWithoutReturnValueAsync(invocation, proceedInfo); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
invocation.ReturnValue = MethodExecuteWithReturnValueAsync |
|
||||
.MakeGenericMethod(invocation.Method.ReturnType.GenericTypeArguments[0]) |
|
||||
.Invoke(this, new object[] {invocation, proceedInfo}); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private async Task ExecuteWithoutReturnValueAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo) |
|
||||
{ |
|
||||
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; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,65 +1,26 @@ |
|||||
using System; |
using System; |
||||
using System.Collections.Generic; |
|
||||
using System.Reflection; |
|
||||
using System.Threading.Tasks; |
using System.Threading.Tasks; |
||||
using Castle.DynamicProxy; |
using Castle.DynamicProxy; |
||||
using Volo.Abp.DynamicProxy; |
using Volo.Abp.DynamicProxy; |
||||
using Volo.Abp.Threading; |
|
||||
|
|
||||
namespace Volo.Abp.Castle.DynamicProxy |
namespace Volo.Abp.Castle.DynamicProxy |
||||
{ |
{ |
||||
public class CastleAbpMethodInvocationAdapter : IAbpMethodInvocation |
public class CastleAbpMethodInvocationAdapter : CastleAbpMethodInvocationAdapterBase, IAbpMethodInvocation |
||||
{ |
{ |
||||
public object[] Arguments => Invocation.Arguments; |
|
||||
|
|
||||
public IReadOnlyDictionary<string, object> ArgumentsDictionary => _lazyArgumentsDictionary.Value; |
|
||||
private readonly Lazy<IReadOnlyDictionary<string, object>> _lazyArgumentsDictionary; |
|
||||
|
|
||||
public Type[] GenericArguments => Invocation.GenericArguments; |
|
||||
|
|
||||
public object TargetObject => Invocation.InvocationTarget ?? Invocation.MethodInvocationTarget; |
|
||||
|
|
||||
public MethodInfo Method => Invocation.MethodInvocationTarget ?? Invocation.Method; |
|
||||
|
|
||||
public object ReturnValue |
|
||||
{ |
|
||||
get => _actualReturnValue ?? Invocation.ReturnValue; |
|
||||
set => Invocation.ReturnValue = value; |
|
||||
} |
|
||||
|
|
||||
private object _actualReturnValue; |
|
||||
|
|
||||
protected IInvocation Invocation { get; } |
|
||||
protected IInvocationProceedInfo ProceedInfo { get; } |
protected IInvocationProceedInfo ProceedInfo { get; } |
||||
|
protected Func<IInvocation, IInvocationProceedInfo, Task> Proceed { get; } |
||||
|
|
||||
public CastleAbpMethodInvocationAdapter(IInvocation invocation, IInvocationProceedInfo proceedInfo) |
public CastleAbpMethodInvocationAdapter(IInvocation invocation, IInvocationProceedInfo proceedInfo, |
||||
|
Func<IInvocation, IInvocationProceedInfo, Task> proceed) |
||||
|
: base(invocation) |
||||
{ |
{ |
||||
Invocation = invocation; |
|
||||
ProceedInfo = proceedInfo; |
ProceedInfo = proceedInfo; |
||||
|
Proceed = proceed; |
||||
_lazyArgumentsDictionary = new Lazy<IReadOnlyDictionary<string, object>>(GetArgumentsDictionary); |
|
||||
} |
|
||||
|
|
||||
public Task ProceedAsync() |
|
||||
{ |
|
||||
ProceedInfo.Invoke(); |
|
||||
|
|
||||
_actualReturnValue = Invocation.ReturnValue; |
|
||||
|
|
||||
return (Task) _actualReturnValue; |
|
||||
} |
} |
||||
|
|
||||
private IReadOnlyDictionary<string, object> GetArgumentsDictionary() |
public override async Task ProceedAsync() |
||||
{ |
{ |
||||
var dict = new Dictionary<string, object>(); |
await Proceed(Invocation, ProceedInfo); |
||||
|
|
||||
var methodParameters = Method.GetParameters(); |
|
||||
for (int i = 0; i < methodParameters.Length; i++) |
|
||||
{ |
|
||||
dict[methodParameters[i].Name] = Invocation.Arguments[i]; |
|
||||
} |
|
||||
|
|
||||
return dict; |
|
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
@ -0,0 +1,48 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Reflection; |
||||
|
using System.Threading.Tasks; |
||||
|
using Castle.DynamicProxy; |
||||
|
using Volo.Abp.DynamicProxy; |
||||
|
|
||||
|
namespace Volo.Abp.Castle.DynamicProxy |
||||
|
{ |
||||
|
public abstract class CastleAbpMethodInvocationAdapterBase : IAbpMethodInvocation |
||||
|
{ |
||||
|
public object[] Arguments => Invocation.Arguments; |
||||
|
|
||||
|
public IReadOnlyDictionary<string, object> ArgumentsDictionary => _lazyArgumentsDictionary.Value; |
||||
|
private readonly Lazy<IReadOnlyDictionary<string, object>> _lazyArgumentsDictionary; |
||||
|
|
||||
|
public Type[] GenericArguments => Invocation.GenericArguments; |
||||
|
|
||||
|
public object TargetObject => Invocation.InvocationTarget ?? Invocation.MethodInvocationTarget; |
||||
|
|
||||
|
public MethodInfo Method => Invocation.MethodInvocationTarget ?? Invocation.Method; |
||||
|
|
||||
|
public object ReturnValue { get; set; } |
||||
|
|
||||
|
protected IInvocation Invocation { get; } |
||||
|
|
||||
|
protected CastleAbpMethodInvocationAdapterBase(IInvocation invocation) |
||||
|
{ |
||||
|
Invocation = invocation; |
||||
|
_lazyArgumentsDictionary = new Lazy<IReadOnlyDictionary<string, object>>(GetArgumentsDictionary); |
||||
|
} |
||||
|
|
||||
|
public abstract Task ProceedAsync(); |
||||
|
|
||||
|
private IReadOnlyDictionary<string, object> GetArgumentsDictionary() |
||||
|
{ |
||||
|
var dict = new Dictionary<string, object>(); |
||||
|
|
||||
|
var methodParameters = Method.GetParameters(); |
||||
|
for (int i = 0; i < methodParameters.Length; i++) |
||||
|
{ |
||||
|
dict[methodParameters[i].Name] = Invocation.Arguments[i]; |
||||
|
} |
||||
|
|
||||
|
return dict; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Castle.DynamicProxy; |
||||
|
using Volo.Abp.DynamicProxy; |
||||
|
|
||||
|
namespace Volo.Abp.Castle.DynamicProxy |
||||
|
{ |
||||
|
public class CastleAbpMethodInvocationAdapterWithReturnValue<TResult> : CastleAbpMethodInvocationAdapterBase, IAbpMethodInvocation |
||||
|
{ |
||||
|
protected IInvocationProceedInfo ProceedInfo { get; } |
||||
|
protected Func<IInvocation, IInvocationProceedInfo, Task<TResult>> Proceed { get; } |
||||
|
|
||||
|
public CastleAbpMethodInvocationAdapterWithReturnValue(IInvocation invocation, |
||||
|
IInvocationProceedInfo proceedInfo, |
||||
|
Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed) |
||||
|
: base(invocation) |
||||
|
{ |
||||
|
ProceedInfo = proceedInfo; |
||||
|
Proceed = proceed; |
||||
|
} |
||||
|
|
||||
|
public override async Task ProceedAsync() |
||||
|
{ |
||||
|
ReturnValue = await Proceed(Invocation, ProceedInfo); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,36 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Castle.DynamicProxy; |
||||
|
using Volo.Abp.DynamicProxy; |
||||
|
|
||||
|
namespace Volo.Abp.Castle.DynamicProxy |
||||
|
{ |
||||
|
public class CastleAsyncAbpInterceptorAdapter<TInterceptor> : AsyncInterceptorBase |
||||
|
where TInterceptor : IAbpInterceptor |
||||
|
{ |
||||
|
private readonly TInterceptor _abpInterceptor; |
||||
|
|
||||
|
public CastleAsyncAbpInterceptorAdapter(TInterceptor abpInterceptor) |
||||
|
{ |
||||
|
_abpInterceptor = abpInterceptor; |
||||
|
} |
||||
|
|
||||
|
protected override async Task InterceptAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task> proceed) |
||||
|
{ |
||||
|
await _abpInterceptor.InterceptAsync( |
||||
|
new CastleAbpMethodInvocationAdapter(invocation, proceedInfo, proceed) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
protected override async Task<TResult> InterceptAsync<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed) |
||||
|
{ |
||||
|
var adapter = new CastleAbpMethodInvocationAdapterWithReturnValue<TResult>(invocation, proceedInfo, proceed); |
||||
|
|
||||
|
await _abpInterceptor.InterceptAsync( |
||||
|
adapter |
||||
|
); |
||||
|
|
||||
|
return (TResult)adapter.ReturnValue; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue