Browse Source

Worked on dynamic http proxying

pull/96/head
Halil İbrahim Kalkan 9 years ago
parent
commit
c3efe16f98
  1. 1
      src/Volo.Abp.AspNetCore.TestBase/Volo.Abp.AspNetCore.TestBase.csproj
  2. 4
      src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreIntegratedTestBase.cs
  3. 2
      src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreTestBaseModule.cs
  4. 22
      src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/DynamicProxying/AspNetCoreTestDynamicProxyHttpClientFactory.cs
  5. 9
      src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/ITestServerAccessor.cs
  6. 10
      src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/TestServerAccessor.cs
  7. 4
      src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs
  8. 2
      src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs
  9. 32
      src/Volo.Abp.Http/Microsoft/Extensions/DependencyInjection/ServiceCollectionHttpProxyExtensions.cs
  10. 1
      src/Volo.Abp.Http/Volo.Abp.Http.csproj
  11. 13
      src/Volo.Abp.Http/Volo/Abp/Http/DynamicProxying/DefaultDynamicProxyHttpClientFactory.cs
  12. 66
      src/Volo.Abp.Http/Volo/Abp/Http/DynamicProxying/DynamicHttpProxyInterceptor.cs
  13. 9
      src/Volo.Abp.Http/Volo/Abp/Http/DynamicProxying/IDynamicProxyHttpClientFactory.cs
  14. 2
      test/Volo.Abp.AspNetCore.Tests/Volo/Abp/AspNetCore/AppTestBase.cs
  15. 1
      test/Volo.Abp.Http.Tests/Volo/Abp/Http/AbpHttpTestBase.cs
  16. 8
      test/Volo.Abp.Http.Tests/Volo/Abp/Http/AbpHttpTestModule.cs
  17. 1
      test/Volo.Abp.Http.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs

1
src/Volo.Abp.AspNetCore.TestBase/Volo.Abp.AspNetCore.TestBase.csproj

@ -13,6 +13,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore\Volo.Abp.AspNetCore.csproj" />
<ProjectReference Include="..\Volo.Abp.Http\Volo.Abp.Http.csproj" />
</ItemGroup>
<ItemGroup>

4
src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreIntegratedTestBase.cs

@ -5,6 +5,7 @@ using System.Net.Http;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
namespace Volo.Abp.AspNetCore.TestBase
{
@ -22,8 +23,9 @@ namespace Volo.Abp.AspNetCore.TestBase
var builder = CreateWebHostBuilder();
Server = CreateTestServer(builder);
Client = Server.CreateClient();
ServiceProvider = Server.Host.Services;
ServiceProvider.GetRequiredService<ITestServerAccessor>().Server = Server;
}
protected virtual IWebHostBuilder CreateWebHostBuilder()

2
src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/AbpAspNetCoreTestBaseModule.cs

@ -1,8 +1,10 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Http;
using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.TestBase
{
[DependsOn(typeof(AbpHttpModule))]
[DependsOn(typeof(AbpAspNetCoreModule))]
public class AbpAspNetCoreTestBaseModule : AbpModule
{

22
src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/DynamicProxying/AspNetCoreTestDynamicProxyHttpClientFactory.cs

@ -0,0 +1,22 @@
using System.Net.Http;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.DynamicProxying;
namespace Volo.Abp.AspNetCore.TestBase.DynamicProxying
{
[Dependency(ReplaceServices = true)]
public class AspNetCoreTestDynamicProxyHttpClientFactory : IDynamicProxyHttpClientFactory, ITransientDependency
{
private readonly ITestServerAccessor _testServerAccessor;
public AspNetCoreTestDynamicProxyHttpClientFactory(ITestServerAccessor testServerAccessor)
{
_testServerAccessor = testServerAccessor;
}
public HttpClient Create()
{
return _testServerAccessor.Server.CreateClient();
}
}
}

9
src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/ITestServerAccessor.cs

@ -0,0 +1,9 @@
using Microsoft.AspNetCore.TestHost;
namespace Volo.Abp.AspNetCore.TestBase
{
public interface ITestServerAccessor
{
TestServer Server { get; set; }
}
}

10
src/Volo.Abp.AspNetCore.TestBase/Volo/Abp/AspNetCore/TestBase/TestServerAccessor.cs

@ -0,0 +1,10 @@
using Microsoft.AspNetCore.TestHost;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.TestBase
{
public class TestServerAccessor : ITestServerAccessor, ISingletonDependency
{
public TestServer Server { get; set; }
}
}

4
src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpInterceptorAdapter.cs

@ -17,7 +17,9 @@ namespace Volo.Abp.Castle.DynamicProxy
public void Intercept(IInvocation invocation)
{
if (invocation.MethodInvocationTarget.IsAsync())
var method = invocation.MethodInvocationTarget ?? invocation.Method;
if (method.IsAsync())
{
InterceptAsyncMethod(invocation);
}

2
src/Volo.Abp.Castle.Core/Volo/Abp/Castle/DynamicProxy/CastleAbpMethodInvocationAdapter.cs

@ -15,7 +15,7 @@ namespace Volo.Abp.Castle.DynamicProxy
public object TargetObject => Invocation.InvocationTarget;
public MethodInfo Method => Invocation.MethodInvocationTarget;
public MethodInfo Method => Invocation.MethodInvocationTarget ?? Invocation.Method;
public object ReturnValue
{

32
src/Volo.Abp.Http/Microsoft/Extensions/DependencyInjection/ServiceCollectionHttpProxyExtensions.cs

@ -0,0 +1,32 @@
using System;
using Castle.DynamicProxy;
using Volo.Abp.Castle.DynamicProxy;
using Volo.Abp.Http;
using Volo.Abp.Http.DynamicProxying;
namespace Microsoft.Extensions.DependencyInjection
{
public static class ServiceCollectionHttpProxyExtensions
{
private static readonly ProxyGenerator ProxyGeneratorInstance = new ProxyGenerator();
public static IServiceCollection AddHttpClientProxy<T>(this IServiceCollection services, string baseUrl)
{
return services.AddHttpClientProxy(typeof(T), baseUrl);
}
public static IServiceCollection AddHttpClientProxy(this IServiceCollection services, Type type, string baseUrl)
{
services.AddTransient(type, serviceProvider =>
{
return ProxyGeneratorInstance
.CreateInterfaceProxyWithoutTarget(
type,
serviceProvider.GetRequiredService<CastleAbpInterceptorAdapter<DynamicHttpProxyInterceptor>>()
);
});
return services;
}
}
}

1
src/Volo.Abp.Http/Volo.Abp.Http.csproj

@ -12,6 +12,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Castle.Core\Volo.Abp.Castle.Core.csproj" />
<ProjectReference Include="..\Volo.Abp\Volo.Abp.csproj" />
</ItemGroup>

13
src/Volo.Abp.Http/Volo/Abp/Http/DynamicProxying/DefaultDynamicProxyHttpClientFactory.cs

@ -0,0 +1,13 @@
using System.Net.Http;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Http.DynamicProxying
{
public class DefaultDynamicProxyHttpClientFactory : IDynamicProxyHttpClientFactory, ITransientDependency
{
public HttpClient Create()
{
return new HttpClient();
}
}
}

66
src/Volo.Abp.Http/Volo/Abp/Http/DynamicProxying/DynamicHttpProxyInterceptor.cs

@ -0,0 +1,66 @@
using System;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy;
namespace Volo.Abp.Http.DynamicProxying
{
public class DynamicHttpProxyInterceptor : AbpInterceptor, ITransientDependency
{
private readonly IDynamicProxyHttpClientFactory _httpClientFactory;
public DynamicHttpProxyInterceptor(IDynamicProxyHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public override void Intercept(IAbpMethodInvocation invocation)
{
throw new System.NotImplementedException();
}
public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{
var returnTypeWithoutTask = invocation.Method.ReturnType.GenericTypeArguments[0];
//var result = await GetResult(client, returnTypeWithoutTask);
var methods = typeof(DynamicHttpProxyInterceptor).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance);
var getResultMethod = methods
.Where(m => m.Name == nameof(GetResult))
.First()
.MakeGenericMethod(returnTypeWithoutTask);
invocation.ReturnValue = getResultMethod.Invoke(this, new object[] { returnTypeWithoutTask });
}
private async Task<T> GetResult<T>(Type returnTypeWithoutTask)
{
using (var client = _httpClientFactory.Create())
{
var response = await client.GetAsync("/api/app/people");
if (!response.IsSuccessStatusCode)
{
throw new AbpException("Remote service returns error!");
}
var content = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject(
content,
returnTypeWithoutTask,
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
return (T)result;
}
}
}
}

9
src/Volo.Abp.Http/Volo/Abp/Http/DynamicProxying/IDynamicProxyHttpClientFactory.cs

@ -0,0 +1,9 @@
using System.Net.Http;
namespace Volo.Abp.Http.DynamicProxying
{
public interface IDynamicProxyHttpClientFactory
{
HttpClient Create();
}
}

2
test/Volo.Abp.AspNetCore.Tests/Volo/Abp/AspNetCore/AppTestBase.cs

@ -6,7 +6,7 @@ using Newtonsoft.Json.Serialization;
using Shouldly;
using Volo.Abp.AspNetCore.TestBase;
namespace Volo.Abp.AspNetCore.App
namespace Volo.Abp.AspNetCore
{
public abstract class AbpAspNetCoreTestBase<TStartup> : AbpAspNetCoreIntegratedTestBase<TStartup>
where TStartup : class

1
test/Volo.Abp.Http.Tests/Volo/Abp/Http/AbpHttpTestBase.cs

@ -1,3 +1,4 @@
using Volo.Abp.AspNetCore;
using Volo.Abp.AspNetCore.App;
namespace Volo.Abp.Http

8
test/Volo.Abp.Http.Tests/Volo/Abp/Http/AbpHttpTestModule.cs

@ -1,6 +1,9 @@
using Microsoft.Extensions.DependencyInjection;
using Castle.DynamicProxy;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.App;
using Volo.Abp.Castle.DynamicProxy;
using Volo.Abp.Modularity;
using Volo.Abp.TestApp.Application;
namespace Volo.Abp.Http
{
@ -9,7 +12,8 @@ namespace Volo.Abp.Http
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddAssemblyOf<AbpAspNetCoreMvcTestModule>();
services.AddAssemblyOf<AbpHttpTestModule>();
services.AddHttpClientProxy<IPeopleAppService>("/");
}
}
}

1
test/Volo.Abp.Http.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs

@ -13,7 +13,6 @@ namespace Volo.Abp.Http.DynamicProxying
public PersonAppServiceClientProxy_Tests()
{
//TODO: Should actually test the proxy!
_peopleAppService = ServiceProvider.GetRequiredService<IPeopleAppService>();
}

Loading…
Cancel
Save