Browse Source

Improved DynamicHttpProxyInterceptor

pull/113/head
Halil İbrahim Kalkan 9 years ago
parent
commit
0083892153
  1. 47
      src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs
  2. 1
      test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PersonAppService_Tests.cs
  3. 5
      test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs
  4. 2
      test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/Dto/GetPersonPhonesFilter.cs
  5. 20
      test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/Dto/GetWithComplexTypeInput.cs
  6. 2
      test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/Dto/PersonDto.cs
  7. 2
      test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/Dto/PhoneDto.cs
  8. 19
      test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPeopleAppService.cs
  9. 1
      test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleAppService.cs
  10. 1
      test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs

47
src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs

@ -12,6 +12,8 @@ using Volo.Abp.Threading;
namespace Volo.Abp.Http.Client.DynamicProxying namespace Volo.Abp.Http.Client.DynamicProxying
{ {
//TODO: Somehow capture cancellationtoken and pass to other methods...?
public class DynamicHttpProxyInterceptor<TService> : AbpInterceptor, ITransientDependency public class DynamicHttpProxyInterceptor<TService> : AbpInterceptor, ITransientDependency
{ {
private static MethodInfo GenericInterceptAsyncMethod { get; } private static MethodInfo GenericInterceptAsyncMethod { get; }
@ -39,47 +41,58 @@ namespace Volo.Abp.Http.Client.DynamicProxying
public override void Intercept(IAbpMethodInvocation invocation) public override void Intercept(IAbpMethodInvocation invocation)
{ {
//TODO: Handle this differently because InterceptAsync assumes that given method is async!
AsyncHelper.RunSync(() => InterceptAsync(invocation)); AsyncHelper.RunSync(() => InterceptAsync(invocation));
} }
public override Task InterceptAsync(IAbpMethodInvocation invocation) public override Task InterceptAsync(IAbpMethodInvocation invocation)
{ {
if (invocation.Method.ReturnType.GenericTypeArguments.IsNullOrEmpty())
{
return MakeRequest(invocation);
}
invocation.ReturnValue = GenericInterceptAsyncMethod invocation.ReturnValue = GenericInterceptAsyncMethod
.MakeGenericMethod(invocation.Method.ReturnType.GenericTypeArguments[0]) .MakeGenericMethod(invocation.Method.ReturnType.GenericTypeArguments[0])
.Invoke(this, new object[] { invocation }); .Invoke(this, new object[] {invocation});
return Task.CompletedTask; return Task.CompletedTask;
} }
private async Task<T> InterceptAsync<T>(IAbpMethodInvocation invocation) private async Task<T> InterceptAsync<T>(IAbpMethodInvocation invocation)
{ {
//TODO: Somehow capture cancellationtoken and pass to other methods...? var content = await MakeRequest(invocation);
var result = JsonConvert.DeserializeObject(
content,
typeof(T),
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
var proxyConfig = GetProxyConfig(); return (T)result;
var actionApiDescription = await _apiDescriptionFinder.FindActionAsync(proxyConfig, invocation.Method); }
private async Task<string> MakeRequest(IAbpMethodInvocation invocation)
{
using (var client = _httpClientFactory.Create()) using (var client = _httpClientFactory.Create())
{ {
var url = proxyConfig.BaseUrl + UrlBuilder.GenerateUrlWithParameters(actionApiDescription, invocation.ArgumentsDictionary); var proxyConfig = GetProxyConfig();
var actionApiDescription = await _apiDescriptionFinder.FindActionAsync(proxyConfig, invocation.Method);
var url = proxyConfig.BaseUrl + UrlBuilder.GenerateUrlWithParameters(actionApiDescription, invocation.ArgumentsDictionary);
var requestMessage = new HttpRequestMessage(actionApiDescription.GetHttpMethod(), url); var requestMessage = new HttpRequestMessage(actionApiDescription.GetHttpMethod(), url);
var response = await client.SendAsync(requestMessage); var response = await client.SendAsync(requestMessage);
if (!response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)
{ {
throw new AbpException("Remote service returns error!"); throw new AbpException($"Remote service returns error! HttpStatusCode: {response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}");
} }
var content = await response.Content.ReadAsStringAsync(); return await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject(
content,
typeof(T),
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
return (T)result;
} }
} }

1
test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PersonAppService_Tests.cs

@ -13,6 +13,7 @@ using System.Net.Http;
using System.Text; using System.Text;
using Volo.Abp.ObjectMapping; using Volo.Abp.ObjectMapping;
using Volo.Abp.Json; using Volo.Abp.Json;
using Volo.Abp.TestApp.Application.Dto;
namespace Volo.Abp.AspNetCore.Mvc namespace Volo.Abp.AspNetCore.Mvc
{ {

5
test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs

@ -5,6 +5,7 @@ using Shouldly;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
using Volo.Abp.TestApp.Application; using Volo.Abp.TestApp.Application;
using Volo.Abp.TestApp.Application.Dto;
using Volo.Abp.TestApp.Domain; using Volo.Abp.TestApp.Domain;
using Xunit; using Xunit;
@ -47,10 +48,10 @@ namespace Volo.Abp.Http.DynamicProxying
new GetWithComplexTypeInput new GetWithComplexTypeInput
{ {
Value1 = "value one", Value1 = "value one",
Inner1 = new GetWithComplexTypeInner Inner1 = new GetWithComplexTypeInput.GetWithComplexTypeInner
{ {
Value2 = "value two", Value2 = "value two",
Inner2 = new GetWithComplexTypeInnerInner Inner2 = new GetWithComplexTypeInput.GetWithComplexTypeInnerInner
{ {
Value3 = "value three" Value3 = "value three"
} }

2
test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/GetPersonPhonesFilter.cs → test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/Dto/GetPersonPhonesFilter.cs

@ -1,6 +1,6 @@
using Volo.Abp.TestApp.Domain; using Volo.Abp.TestApp.Domain;
namespace Volo.Abp.TestApp.Application namespace Volo.Abp.TestApp.Application.Dto
{ {
public class GetPersonPhonesFilter public class GetPersonPhonesFilter
{ {

20
test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/Dto/GetWithComplexTypeInput.cs

@ -0,0 +1,20 @@
namespace Volo.Abp.TestApp.Application.Dto
{
public class GetWithComplexTypeInput
{
public string Value1 { get; set; }
public GetWithComplexTypeInner Inner1 { get; set; }
public class GetWithComplexTypeInner
{
public string Value2 { get; set; }
public GetWithComplexTypeInnerInner Inner2 { get; set; }
}
public class GetWithComplexTypeInnerInner
{
public string Value3 { get; set; }
}
}
}

2
test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PersonDto.cs → test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/Dto/PersonDto.cs

@ -1,6 +1,6 @@
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
namespace Volo.Abp.TestApp.Application namespace Volo.Abp.TestApp.Application.Dto
{ {
public class PersonDto : EntityDto public class PersonDto : EntityDto
{ {

2
test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PhoneDto.cs → test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/Dto/PhoneDto.cs

@ -1,7 +1,7 @@
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.TestApp.Domain; using Volo.Abp.TestApp.Domain;
namespace Volo.Abp.TestApp.Application namespace Volo.Abp.TestApp.Application.Dto
{ {
public class PhoneDto : EntityDto<long> public class PhoneDto : EntityDto<long>
{ {

19
test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/IPeopleAppService.cs

@ -2,6 +2,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Abp.TestApp.Application.Dto;
namespace Volo.Abp.TestApp.Application namespace Volo.Abp.TestApp.Application
{ {
@ -15,22 +16,4 @@ namespace Volo.Abp.TestApp.Application
Task<GetWithComplexTypeInput> GetWithComplexType(GetWithComplexTypeInput input); Task<GetWithComplexTypeInput> GetWithComplexType(GetWithComplexTypeInput input);
} }
public class GetWithComplexTypeInput
{
public string Value1 { get; set; }
public GetWithComplexTypeInner Inner1 { get; set; }
}
public class GetWithComplexTypeInner
{
public string Value2 { get; set; }
public GetWithComplexTypeInnerInner Inner2 { get; set; }
}
public class GetWithComplexTypeInnerInner
{
public string Value3 { get; set; }
}
} }

1
test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleAppService.cs

@ -6,6 +6,7 @@ using Volo.Abp.Application.Dtos;
using Volo.Abp.TestApp.Domain; using Volo.Abp.TestApp.Domain;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Abp.TestApp.Application.Dto;
namespace Volo.Abp.TestApp.Application namespace Volo.Abp.TestApp.Application
{ {

1
test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs

@ -3,6 +3,7 @@ using Volo.Abp.Modularity;
using Volo.Abp.TestApp.Domain; using Volo.Abp.TestApp.Domain;
using Volo.Abp.AutoMapper; using Volo.Abp.AutoMapper;
using Volo.Abp.TestApp.Application; using Volo.Abp.TestApp.Application;
using Volo.Abp.TestApp.Application.Dto;
namespace Volo.Abp.TestApp namespace Volo.Abp.TestApp
{ {

Loading…
Cancel
Save