Skip to content

Commit

Permalink
Use Castle.Core.AsyncInterceptor
Browse files Browse the repository at this point in the history
  • Loading branch information
hikalkan committed Dec 24, 2019
1 parent c4b2d2b commit f608474
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ private static IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle>
foreach (var interceptor in interceptors)
{
registrationBuilder.InterceptedBy(
typeof(CastleAbpInterceptorAdapter<>).MakeGenericType(interceptor)
typeof(AbpAsyncDeterminationInterceptor<>).MakeGenericType(interceptor)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

<ItemGroup>
<PackageReference Include="Castle.Core" Version="4.4.0" />
<PackageReference Include="Castle.Core.AsyncInterceptor" Version="2.0.21-alpha" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class AbpCastleCoreModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddTransient(typeof(CastleAbpInterceptorAdapter<>));
context.Services.AddTransient(typeof(AbpAsyncDeterminationInterceptor<>));
}
}
}
Original file line number Diff line number Diff line change
@@ -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))
{

}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,65 +1,26 @@
using System;
using System.Collections.Generic;
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 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 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;

_lazyArgumentsDictionary = new Lazy<IReadOnlyDictionary<string, object>>(GetArgumentsDictionary);
}

public Task ProceedAsync()
{
ProceedInfo.Invoke();

_actualReturnValue = Invocation.ReturnValue;

return (Task) _actualReturnValue;
Proceed = proceed;
}

private IReadOnlyDictionary<string, object> GetArgumentsDictionary()
public override async Task ProceedAsync()
{
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;
await Proceed(Invocation, ProceedInfo);
}
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public static IServiceCollection AddHttpClientProxies(
foreach (var serviceType in serviceTypes)
{
services.AddHttpClientProxy(
serviceType,
serviceType,
remoteServiceConfigurationName,
asDefaultServices
);
Expand Down Expand Up @@ -153,7 +153,7 @@ public static IServiceCollection AddHttpClientProxy(
var interceptorType = typeof(DynamicHttpProxyInterceptor<>).MakeGenericType(type);
services.AddTransient(interceptorType);

var interceptorAdapterType = typeof(CastleAbpInterceptorAdapter<>).MakeGenericType(interceptorType);
var interceptorAdapterType = typeof(AbpAsyncDeterminationInterceptor<>).MakeGenericType(interceptorType);

if (asDefaultService)
{
Expand All @@ -174,7 +174,7 @@ public static IServiceCollection AddHttpClientProxy(
var service = ProxyGeneratorInstance
.CreateInterfaceProxyWithoutTarget(
type,
(IInterceptor) serviceProvider.GetRequiredService(interceptorAdapterType)
(IInterceptor)serviceProvider.GetRequiredService(interceptorAdapterType)
);

return Activator.CreateInstance(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,33 @@ public DynamicHttpProxyInterceptor(
Logger = NullLogger<DynamicHttpProxyInterceptor<TService>>.Instance;
}

public override Task InterceptAsync(IAbpMethodInvocation invocation)
public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{
if (invocation.Method.ReturnType.GenericTypeArguments.IsNullOrEmpty())
{
return MakeRequestAsync(invocation);
await MakeRequestAsync(invocation);
}
else
{
var result = (Task)GenericInterceptAsyncMethod
.MakeGenericMethod(invocation.Method.ReturnType.GenericTypeArguments[0])
.Invoke(this, new object[] { invocation });

invocation.ReturnValue = GenericInterceptAsyncMethod
.MakeGenericMethod(invocation.Method.ReturnType.GenericTypeArguments[0])
.Invoke(this, new object[] { invocation });
invocation.ReturnValue = await GetResultAsync(
result,
invocation.Method.ReturnType.GetGenericArguments()[0]
);
}

return Task.CompletedTask;
}

private async Task<object> GetResultAsync(Task task, Type resultType)
{
await task;
return typeof(Task<>)
.MakeGenericType(resultType)
.GetProperty(nameof(Task<object>.Result), BindingFlags.Instance | BindingFlags.Public)
.GetValue(task);
}

private async Task<T> MakeRequestAndGetResultAsync<T>(IAbpMethodInvocation invocation)
Expand Down Expand Up @@ -138,7 +153,6 @@ await ClientAuthenticator.Authenticate(
return await response.Content.ReadAsStringAsync();
}


private ApiVersionInfo GetApiVersionInfo(ActionApiDescriptionModel action)
{
var apiVersion = FindBestApiVersion(action);
Expand Down

0 comments on commit f608474

Please sign in to comment.