Browse Source
1:增加 **LINGYUN.Abp.Http.Client.Wrapper**模块,依赖此模块自动识别远程客户端代理时是否使用包装器; 2:**LINGYUN.Abp.Dapr.Client**增加接口方法**AddStaticDaprClientProxies**,可以通过***.generate-proxy.json**配置文件调用远程接口;pull/684/head
23 changed files with 476 additions and 312 deletions
@ -0,0 +1,33 @@ |
|||
using LINGYUN.Abp.Wrapper; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.Http.Client; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Http.Client.Wrapper; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpHttpClientModule), |
|||
typeof(AbpWrapperModule))] |
|||
public class AbpHttpClientWrapperModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<AbpHttpClientBuilderOptions>(options => |
|||
{ |
|||
options.ProxyClientBuildActions.Add( |
|||
(_, builder) => |
|||
{ |
|||
builder.ConfigureHttpClient((provider, client) => |
|||
{ |
|||
var wrapperOptions = provider.GetRequiredService<IOptions<AbpWrapperOptions>>(); |
|||
var wrapperHeader = wrapperOptions.Value.IsEnabled |
|||
? AbpHttpWrapConsts.AbpWrapResult |
|||
: AbpHttpWrapConsts.AbpDontWrapResult; |
|||
|
|||
client.DefaultRequestHeaders.TryAddWithoutValidation(wrapperHeader, "true"); |
|||
}); |
|||
}); |
|||
}); |
|||
} |
|||
} |
|||
@ -1,13 +0,0 @@ |
|||
using LINGYUN.Abp.Wrapper; |
|||
using Volo.Abp.Http.Client; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.HttpClient.Wrapper |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpHttpClientModule), |
|||
typeof(AbpWrapperModule))] |
|||
public class AbpHttpClientWrapperModule : AbpModule |
|||
{ |
|||
} |
|||
} |
|||
@ -1,153 +0,0 @@ |
|||
using LINGYUN.Abp.Wrapper; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Net.Http; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Content; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Http; |
|||
using Volo.Abp.Http.Client; |
|||
using Volo.Abp.Http.Client.Authentication; |
|||
using Volo.Abp.Http.Client.ClientProxying; |
|||
using Volo.Abp.Http.Client.DynamicProxying; |
|||
|
|||
namespace LINGYUN.Abp.HttpClient.Wrapper |
|||
{ |
|||
[Dependency(ReplaceServices = true)] |
|||
[ExposeServices(typeof(DynamicHttpProxyInterceptorClientProxy<>))] |
|||
public class DynamicHttpProxyInterceptorWrapClientProxy<TService> |
|||
: DynamicHttpProxyInterceptorClientProxy<TService>, ITransientDependency |
|||
{ |
|||
protected IOptions<AbpWrapperOptions> WrapperOptions => LazyServiceProvider.LazyGetRequiredService<IOptions<AbpWrapperOptions>>(); |
|||
|
|||
protected override async Task<T> RequestAsync<T>(ClientProxyRequestContext requestContext) |
|||
{ |
|||
var response = await RequestAndGetResponseAsync(requestContext); |
|||
|
|||
var responseContent = response.Content; |
|||
|
|||
if (typeof(T) == typeof(IRemoteStreamContent) || |
|||
typeof(T) == typeof(RemoteStreamContent)) |
|||
{ |
|||
/* returning a class that holds a reference to response |
|||
* content just to be sure that GC does not dispose of |
|||
* it before we finish doing our work with the stream */ |
|||
return (T)(object)new RemoteStreamContent( |
|||
await responseContent.ReadAsStreamAsync(), |
|||
responseContent.Headers?.ContentDisposition?.FileNameStar ?? |
|||
RemoveQuotes(responseContent.Headers?.ContentDisposition?.FileName).ToString(), |
|||
responseContent.Headers?.ContentType?.ToString(), |
|||
responseContent.Headers?.ContentLength); |
|||
} |
|||
|
|||
var stringContent = await responseContent.ReadAsStringAsync(); |
|||
|
|||
if (stringContent.IsNullOrWhiteSpace()) |
|||
{ |
|||
return default; |
|||
} |
|||
|
|||
// 对于包装后的结果需要处理
|
|||
if (response.Headers.Contains(AbpHttpWrapConsts.AbpWrapResult)) |
|||
{ |
|||
var wrapResult = JsonSerializer.Deserialize<WrapResult<T>>(stringContent); |
|||
|
|||
ThrowExceptionForResponse(wrapResult); |
|||
|
|||
if (typeof(T) == typeof(string)) |
|||
{ |
|||
return (T)(object)wrapResult.Result; |
|||
} |
|||
|
|||
return wrapResult.Result; |
|||
} |
|||
|
|||
if (typeof(T) == typeof(string)) |
|||
{ |
|||
return (T)(object)stringContent; |
|||
} |
|||
|
|||
if (stringContent.IsNullOrWhiteSpace()) |
|||
{ |
|||
return default; |
|||
} |
|||
|
|||
return JsonSerializer.Deserialize<T>(stringContent); |
|||
} |
|||
|
|||
public override async Task<HttpContent> CallRequestAsync(ClientProxyRequestContext requestContext) |
|||
{ |
|||
var response = await RequestAndGetResponseAsync(requestContext); |
|||
// 对于包装后的结果需要处理
|
|||
if (response.Headers.Contains(AbpHttpWrapConsts.AbpWrapResult)) |
|||
{ |
|||
var stringContent = await response.Content.ReadAsStringAsync(); |
|||
var wrapResult = JsonSerializer.Deserialize<WrapResult>(stringContent); |
|||
|
|||
ThrowExceptionForResponse(wrapResult); |
|||
} |
|||
|
|||
return response.Content; |
|||
} |
|||
|
|||
protected virtual void ThrowExceptionForResponse<T>(WrapResult<T> wrapResult) |
|||
{ |
|||
if (!string.Equals(wrapResult.Code, WrapperOptions.Value.CodeWithSuccess)) |
|||
{ |
|||
var errorInfo = new RemoteServiceErrorInfo( |
|||
wrapResult.Message, |
|||
wrapResult.Details, |
|||
wrapResult.Code); |
|||
throw new AbpRemoteCallException(errorInfo) |
|||
{ |
|||
HttpStatusCode = (int)WrapperOptions.Value.HttpStatusCode |
|||
}; |
|||
} |
|||
} |
|||
|
|||
protected virtual async Task<HttpResponseMessage> RequestAndGetResponseAsync(ClientProxyRequestContext requestContext) |
|||
{ |
|||
var clientConfig = ClientOptions.Value.HttpClientProxies.GetOrDefault(requestContext.ServiceType) ?? throw new AbpException($"Could not get HttpClientProxyConfig for {requestContext.ServiceType.FullName}."); |
|||
var remoteServiceConfig = await RemoteServiceConfigurationProvider.GetConfigurationOrDefaultAsync(clientConfig.RemoteServiceName); |
|||
|
|||
var client = HttpClientFactory.Create(clientConfig.RemoteServiceName); |
|||
|
|||
var apiVersion = await GetApiVersionInfoAsync(requestContext); |
|||
var url = remoteServiceConfig.BaseUrl.EnsureEndsWith('/') + await GetUrlWithParametersAsync(requestContext, apiVersion); |
|||
|
|||
var requestMessage = new HttpRequestMessage(requestContext.Action.GetHttpMethod(), url) |
|||
{ |
|||
Content = await ClientProxyRequestPayloadBuilder.BuildContentAsync(requestContext.Action, requestContext.Arguments, JsonSerializer, apiVersion) |
|||
}; |
|||
|
|||
AddHeaders(requestContext.Arguments, requestContext.Action, requestMessage, apiVersion); |
|||
|
|||
if (requestContext.Action.AllowAnonymous != true) |
|||
{ |
|||
await ClientAuthenticator.Authenticate( |
|||
new RemoteServiceHttpClientAuthenticateContext( |
|||
client, |
|||
requestMessage, |
|||
remoteServiceConfig, |
|||
clientConfig.RemoteServiceName |
|||
) |
|||
); |
|||
} |
|||
|
|||
var response = await client.SendAsync( |
|||
requestMessage, |
|||
HttpCompletionOption.ResponseHeadersRead /*this will buffer only the headers, the content will be used as a stream*/, |
|||
GetCancellationToken(requestContext.Arguments) |
|||
); |
|||
|
|||
if (!response.IsSuccessStatusCode) |
|||
{ |
|||
await ThrowExceptionForResponseAsync(response); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
} |
|||
} |
|||
@ -1,10 +1,11 @@ |
|||
using System; |
|||
using LINGYUN.Abp.Dapr.Client.DynamicProxying; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Net.Http; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.Dapr.Client.DynamicProxying |
|||
namespace LINGYUN.Abp.Dapr.Client.ClientProxying |
|||
{ |
|||
public class AbpDaprClientProxyOptions |
|||
{ |
|||
@ -0,0 +1,124 @@ |
|||
using Dapr.Client; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Net.Http; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Content; |
|||
using Volo.Abp.Http.Client.Authentication; |
|||
using Volo.Abp.Http.Client.ClientProxying; |
|||
|
|||
namespace LINGYUN.Abp.Dapr.Client.ClientProxying |
|||
{ |
|||
public abstract class DaprClientProxyBase<TService> : ClientProxyBase<TService> |
|||
{ |
|||
protected IOptions<AbpDaprClientProxyOptions> DaprClientProxyOptions => LazyServiceProvider.LazyGetRequiredService<IOptions<AbpDaprClientProxyOptions>>(); |
|||
protected IDaprClientFactory DaprClientFactory => LazyServiceProvider.LazyGetRequiredService<IDaprClientFactory>(); |
|||
|
|||
protected async override Task<T> RequestAsync<T>(ClientProxyRequestContext requestContext) |
|||
{ |
|||
var response = await MakeRequestAsync(requestContext); |
|||
|
|||
var responseContent = response.Content; |
|||
|
|||
if (typeof(T) == typeof(IRemoteStreamContent) || |
|||
typeof(T) == typeof(RemoteStreamContent)) |
|||
{ |
|||
/* returning a class that holds a reference to response |
|||
* content just to be sure that GC does not dispose of |
|||
* it before we finish doing our work with the stream */ |
|||
return (T)(object)new RemoteStreamContent( |
|||
await responseContent.ReadAsStreamAsync(), |
|||
responseContent.Headers?.ContentDisposition?.FileNameStar ?? |
|||
RemoveQuotes(responseContent.Headers?.ContentDisposition?.FileName).ToString(), |
|||
responseContent.Headers?.ContentType?.ToString(), |
|||
responseContent.Headers?.ContentLength); |
|||
} |
|||
|
|||
var stringContent = await DaprClientProxyOptions |
|||
.Value |
|||
.ProxyResponseContent(response, LazyServiceProvider); |
|||
|
|||
if (stringContent.IsNullOrWhiteSpace()) |
|||
{ |
|||
return default; |
|||
} |
|||
|
|||
if (typeof(T) == typeof(string)) |
|||
{ |
|||
return (T)(object)stringContent; |
|||
} |
|||
|
|||
return JsonSerializer.Deserialize<T>(stringContent); |
|||
} |
|||
|
|||
protected async override Task<string> GetConfiguredApiVersionAsync(ClientProxyRequestContext requestContext) |
|||
{ |
|||
var clientConfig = DaprClientProxyOptions.Value.DaprClientProxies.GetOrDefault(requestContext.ServiceType) |
|||
?? throw new AbpException($"Could not get DynamicDaprClientProxyConfig for {requestContext.ServiceType.FullName}."); |
|||
var remoteServiceConfig = await RemoteServiceConfigurationProvider.GetConfigurationOrDefaultAsync(clientConfig.RemoteServiceName); |
|||
|
|||
return remoteServiceConfig?.Version; |
|||
} |
|||
|
|||
private async Task<HttpResponseMessage> MakeRequestAsync(ClientProxyRequestContext requestContext) |
|||
{ |
|||
var clientConfig = DaprClientProxyOptions.Value.DaprClientProxies.GetOrDefault(requestContext.ServiceType) ?? throw new AbpException($"Could not get DaprClientProxyConfig for {requestContext.ServiceType.FullName}."); |
|||
var remoteServiceConfig = await RemoteServiceConfigurationProvider.GetConfigurationOrDefaultAsync(clientConfig.RemoteServiceName); |
|||
|
|||
var appId = remoteServiceConfig.GetAppId(); |
|||
var apiVersion = await GetApiVersionInfoAsync(requestContext); |
|||
var methodName = await GetUrlWithParametersAsync(requestContext, apiVersion); |
|||
// See: https://docs.dapr.io/reference/api/service_invocation_api/#examples
|
|||
var daprClient = DaprClientFactory.CreateClient(clientConfig.RemoteServiceName); |
|||
var requestMessage = daprClient.CreateInvokeMethodRequest( |
|||
requestContext.Action.GetHttpMethod(), |
|||
appId, |
|||
methodName); |
|||
requestMessage.Content = await ClientProxyRequestPayloadBuilder.BuildContentAsync( |
|||
requestContext.Action, |
|||
requestContext.Arguments, |
|||
JsonSerializer, |
|||
apiVersion); |
|||
|
|||
AddHeaders(requestContext.Arguments, requestContext.Action, requestMessage, apiVersion); |
|||
|
|||
if (requestContext.Action.AllowAnonymous != true) |
|||
{ |
|||
var httpClient = HttpClientFactory.Create(AbpDaprClientModule.DaprHttpClient); |
|||
|
|||
await ClientAuthenticator.Authenticate( |
|||
new RemoteServiceHttpClientAuthenticateContext( |
|||
httpClient, |
|||
requestMessage, |
|||
remoteServiceConfig, |
|||
clientConfig.RemoteServiceName |
|||
) |
|||
); |
|||
|
|||
// 其他库可能将授权标头写入到HttpClient中
|
|||
if (requestMessage.Headers.Authorization == null && |
|||
httpClient.DefaultRequestHeaders.Authorization != null) |
|||
{ |
|||
requestMessage.Headers.Authorization = httpClient.DefaultRequestHeaders.Authorization; |
|||
} |
|||
} |
|||
|
|||
// 增加一个可配置的请求消息
|
|||
foreach (var clientRequestAction in DaprClientProxyOptions.Value.ProxyRequestActions) |
|||
{ |
|||
clientRequestAction(appId, requestMessage); |
|||
} |
|||
|
|||
var response = await daprClient.InvokeMethodWithResponseAsync(requestMessage, GetCancellationToken(requestContext.Arguments)); |
|||
|
|||
if (!response.IsSuccessStatusCode) |
|||
{ |
|||
await ThrowExceptionForResponseAsync(response); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
} |
|||
} |
|||
@ -1,134 +1,20 @@ |
|||
using Dapr.Client; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using LINGYUN.Abp.Dapr.Client.ClientProxying; |
|||
using System.Net.Http; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Content; |
|||
using Volo.Abp.Http.Client.Authentication; |
|||
using Volo.Abp.Http.Client.ClientProxying; |
|||
|
|||
namespace LINGYUN.Abp.Dapr.Client.DynamicProxying |
|||
{ |
|||
public class DynamicDaprProxyInterceptorClientProxy<TService> : ClientProxyBase<TService> |
|||
public class DynamicDaprProxyInterceptorClientProxy<TService> : DaprClientProxyBase<TService> |
|||
{ |
|||
protected IOptions<AbpDaprClientProxyOptions> DaprClientProxyOptions => LazyServiceProvider.LazyGetRequiredService<IOptions<AbpDaprClientProxyOptions>>(); |
|||
protected IDaprClientFactory DaprClientFactory => LazyServiceProvider.LazyGetRequiredService<IDaprClientFactory>(); |
|||
|
|||
public virtual async Task<T> CallRequestAsync<T>(ClientProxyRequestContext requestContext) |
|||
public async virtual Task<T> CallRequestAsync<T>(ClientProxyRequestContext requestContext) |
|||
{ |
|||
return await RequestAsync<T>(requestContext); |
|||
} |
|||
|
|||
public virtual async Task<HttpContent> CallRequestAsync(ClientProxyRequestContext requestContext) |
|||
public async virtual Task<HttpContent> CallRequestAsync(ClientProxyRequestContext requestContext) |
|||
{ |
|||
return await RequestAsync(requestContext); |
|||
} |
|||
|
|||
protected override async Task<T> RequestAsync<T>(ClientProxyRequestContext requestContext) |
|||
{ |
|||
var response = await MakeRequestAsync(requestContext); |
|||
|
|||
var responseContent = response.Content; |
|||
|
|||
if (typeof(T) == typeof(IRemoteStreamContent) || |
|||
typeof(T) == typeof(RemoteStreamContent)) |
|||
{ |
|||
/* returning a class that holds a reference to response |
|||
* content just to be sure that GC does not dispose of |
|||
* it before we finish doing our work with the stream */ |
|||
return (T)(object)new RemoteStreamContent( |
|||
await responseContent.ReadAsStreamAsync(), |
|||
responseContent.Headers?.ContentDisposition?.FileNameStar ?? |
|||
RemoveQuotes(responseContent.Headers?.ContentDisposition?.FileName).ToString(), |
|||
responseContent.Headers?.ContentType?.ToString(), |
|||
responseContent.Headers?.ContentLength); |
|||
} |
|||
|
|||
var stringContent = await DaprClientProxyOptions |
|||
.Value |
|||
.ProxyResponseContent(response, LazyServiceProvider); |
|||
|
|||
if (stringContent.IsNullOrWhiteSpace()) |
|||
{ |
|||
return default; |
|||
} |
|||
|
|||
if (typeof(T) == typeof(string)) |
|||
{ |
|||
return (T)(object)stringContent; |
|||
} |
|||
|
|||
return JsonSerializer.Deserialize<T>(stringContent); |
|||
} |
|||
|
|||
protected override async Task<string> GetConfiguredApiVersionAsync(ClientProxyRequestContext requestContext) |
|||
{ |
|||
var clientConfig = DaprClientProxyOptions.Value.DaprClientProxies.GetOrDefault(requestContext.ServiceType) |
|||
?? throw new AbpException($"Could not get DynamicDaprClientProxyConfig for {requestContext.ServiceType.FullName}."); |
|||
var remoteServiceConfig = await RemoteServiceConfigurationProvider.GetConfigurationOrDefaultAsync(clientConfig.RemoteServiceName); |
|||
|
|||
return remoteServiceConfig?.Version; |
|||
} |
|||
|
|||
private async Task<HttpResponseMessage> MakeRequestAsync(ClientProxyRequestContext requestContext) |
|||
{ |
|||
var clientConfig = DaprClientProxyOptions.Value.DaprClientProxies.GetOrDefault(requestContext.ServiceType) ?? throw new AbpException($"Could not get DaprClientProxyConfig for {requestContext.ServiceType.FullName}."); |
|||
var remoteServiceConfig = await RemoteServiceConfigurationProvider.GetConfigurationOrDefaultAsync(clientConfig.RemoteServiceName); |
|||
|
|||
var appId = remoteServiceConfig.GetAppId(); |
|||
var apiVersion = await GetApiVersionInfoAsync(requestContext); |
|||
var methodName = await GetUrlWithParametersAsync(requestContext, apiVersion); |
|||
// See: https://docs.dapr.io/reference/api/service_invocation_api/#examples
|
|||
var daprClient = DaprClientFactory.CreateClient(clientConfig.RemoteServiceName); |
|||
var requestMessage = daprClient.CreateInvokeMethodRequest( |
|||
requestContext.Action.GetHttpMethod(), |
|||
appId, |
|||
methodName); |
|||
requestMessage.Content = await ClientProxyRequestPayloadBuilder.BuildContentAsync( |
|||
requestContext.Action, |
|||
requestContext.Arguments, |
|||
JsonSerializer, |
|||
apiVersion); |
|||
|
|||
AddHeaders(requestContext.Arguments, requestContext.Action, requestMessage, apiVersion); |
|||
|
|||
if (requestContext.Action.AllowAnonymous != true) |
|||
{ |
|||
var httpClient = HttpClientFactory.Create(AbpDaprClientModule.DaprHttpClient); |
|||
|
|||
await ClientAuthenticator.Authenticate( |
|||
new RemoteServiceHttpClientAuthenticateContext( |
|||
httpClient, |
|||
requestMessage, |
|||
remoteServiceConfig, |
|||
clientConfig.RemoteServiceName |
|||
) |
|||
); |
|||
|
|||
// 其他库可能将授权标头写入到HttpClient中
|
|||
if (requestMessage.Headers.Authorization == null && |
|||
httpClient.DefaultRequestHeaders.Authorization != null) |
|||
{ |
|||
requestMessage.Headers.Authorization = httpClient.DefaultRequestHeaders.Authorization; |
|||
} |
|||
} |
|||
|
|||
// 增加一个可配置的请求消息
|
|||
foreach (var clientRequestAction in DaprClientProxyOptions.Value.ProxyRequestActions) |
|||
{ |
|||
clientRequestAction(appId, requestMessage); |
|||
} |
|||
|
|||
var response = await daprClient.InvokeMethodWithResponseAsync(requestMessage, GetCancellationToken(requestContext.Arguments)); |
|||
|
|||
if (!response.IsSuccessStatusCode) |
|||
{ |
|||
await ThrowExceptionForResponseAsync(response); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,45 @@ |
|||
// This file is automatically generated by ABP framework to use MVC Controllers from CSharp
|
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Http.Client; |
|||
using Volo.Abp.Http.Modeling; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Http.Client.ClientProxying; |
|||
using LINGYUN.Abp.Dapr.ServiceInvocation; |
|||
using LINGYUN.Abp.Dapr; |
|||
using System.Linq; |
|||
using Volo.Abp; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Reflection; |
|||
using System.Net.Http; |
|||
using LINGYUN.Abp.Dapr.Client.ClientProxying; |
|||
|
|||
// ReSharper disable once CheckNamespace
|
|||
namespace LINGYUN.Abp.Dapr.ServiceInvocation.ClientProxies; |
|||
|
|||
[Dependency(ReplaceServices = true)] |
|||
[ExposeServices(typeof(ITestAppService), typeof(TestClientProxy))] |
|||
public partial class TestClientProxy : DaprClientProxyBase<ITestAppService>, ITestAppService |
|||
{ |
|||
public virtual async Task<ListResultDto<NameValue>> GetAsync() |
|||
{ |
|||
return await RequestAsync<ListResultDto<NameValue>>(nameof(GetAsync)); |
|||
} |
|||
|
|||
public virtual async Task<NameValue> UpdateAsync(int inctement) |
|||
{ |
|||
return await RequestAsync<NameValue>(nameof(UpdateAsync), new ClientProxyRequestTypeValue |
|||
{ |
|||
{ typeof(int), inctement } |
|||
}); |
|||
} |
|||
|
|||
public virtual async Task<TestNeedWrapObject> GetWrapedAsync(string name) |
|||
{ |
|||
return await RequestAsync<TestNeedWrapObject>(nameof(GetWrapedAsync), new ClientProxyRequestTypeValue |
|||
{ |
|||
{ typeof(string), name } |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
// This file is part of TestClientProxy, you can customize it here
|
|||
// ReSharper disable once CheckNamespace
|
|||
namespace LINGYUN.Abp.Dapr.ServiceInvocation.ClientProxies; |
|||
|
|||
public partial class TestClientProxy |
|||
{ |
|||
} |
|||
@ -0,0 +1,114 @@ |
|||
{ |
|||
"modules": { |
|||
"app": { |
|||
"rootPath": "app", |
|||
"remoteServiceName": "TestDapr", |
|||
"controllers": { |
|||
"LINGYUN.Abp.Dapr.ServiceInvocation.TestAppService": { |
|||
"controllerName": "Test", |
|||
"controllerGroupName": "Test", |
|||
"isRemoteService": true, |
|||
"apiVersion": null, |
|||
"type": "LINGYUN.Abp.Dapr.ServiceInvocation.TestAppService", |
|||
"interfaces": [ |
|||
{ |
|||
"type": "LINGYUN.Abp.Dapr.ServiceInvocation.ITestAppService" |
|||
} |
|||
], |
|||
"actions": { |
|||
"GetAsync": { |
|||
"uniqueName": "GetAsync", |
|||
"name": "GetAsync", |
|||
"httpMethod": "GET", |
|||
"url": "api/dapr/test", |
|||
"supportedVersions": [], |
|||
"parametersOnMethod": [], |
|||
"parameters": [], |
|||
"returnValue": { |
|||
"type": "Volo.Abp.Application.Dtos.ListResultDto<LINGYUN.Abp.Dapr.NameValue>", |
|||
"typeSimple": "Volo.Abp.Application.Dtos.ListResultDto<LINGYUN.Abp.Dapr.NameValue>" |
|||
}, |
|||
"allowAnonymous": null, |
|||
"implementFrom": "LINGYUN.Abp.Dapr.ServiceInvocation.ITestAppService" |
|||
}, |
|||
"UpdateAsyncByInctement": { |
|||
"uniqueName": "UpdateAsyncByInctement", |
|||
"name": "UpdateAsync", |
|||
"httpMethod": "PUT", |
|||
"url": "api/dapr/test", |
|||
"supportedVersions": [], |
|||
"parametersOnMethod": [ |
|||
{ |
|||
"name": "inctement", |
|||
"typeAsString": "System.Int32, System.Private.CoreLib", |
|||
"type": "System.Int32", |
|||
"typeSimple": "number", |
|||
"isOptional": false, |
|||
"defaultValue": null |
|||
} |
|||
], |
|||
"parameters": [ |
|||
{ |
|||
"nameOnMethod": "inctement", |
|||
"name": "inctement", |
|||
"jsonName": null, |
|||
"type": "System.Int32", |
|||
"typeSimple": "number", |
|||
"isOptional": false, |
|||
"defaultValue": null, |
|||
"constraintTypes": null, |
|||
"bindingSourceId": "ModelBinding", |
|||
"descriptorName": "" |
|||
} |
|||
], |
|||
"returnValue": { |
|||
"type": "LINGYUN.Abp.Dapr.NameValue", |
|||
"typeSimple": "LINGYUN.Abp.Dapr.NameValue" |
|||
}, |
|||
"allowAnonymous": null, |
|||
"implementFrom": "LINGYUN.Abp.Dapr.ServiceInvocation.ITestAppService" |
|||
}, |
|||
"GetWrapedAsyncByName": { |
|||
"uniqueName": "GetWrapedAsyncByName", |
|||
"name": "GetWrapedAsync", |
|||
"httpMethod": "GET", |
|||
"url": "api/dapr/test/{name}", |
|||
"supportedVersions": [], |
|||
"parametersOnMethod": [ |
|||
{ |
|||
"name": "name", |
|||
"typeAsString": "System.String, System.Private.CoreLib", |
|||
"type": "System.String", |
|||
"typeSimple": "string", |
|||
"isOptional": false, |
|||
"defaultValue": null |
|||
} |
|||
], |
|||
"parameters": [ |
|||
{ |
|||
"nameOnMethod": "name", |
|||
"name": "name", |
|||
"jsonName": null, |
|||
"type": "System.String", |
|||
"typeSimple": "string", |
|||
"isOptional": false, |
|||
"defaultValue": null, |
|||
"constraintTypes": [], |
|||
"bindingSourceId": "Path", |
|||
"descriptorName": "" |
|||
} |
|||
], |
|||
"returnValue": { |
|||
"type": "LINGYUN.Abp.Dapr.TestNeedWrapObject", |
|||
"typeSimple": "LINGYUN.Abp.Dapr.TestNeedWrapObject" |
|||
}, |
|||
"allowAnonymous": null, |
|||
"implementFrom": "LINGYUN.Abp.Dapr.ServiceInvocation.ITestAppService" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"types": {} |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
using LINGYUN.Abp.Dapr.ServiceInvocation; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Shouldly; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Xunit; |
|||
|
|||
namespace LINGYUN.Abp.Dapr.Client.Tests |
|||
{ |
|||
public class TestAppServiceStaticProxyTests : AbpDaptClientTestBase |
|||
{ |
|||
private readonly ITestAppService _service; |
|||
|
|||
public TestAppServiceStaticProxyTests() |
|||
{ |
|||
_service = GetRequiredService<ITestAppService>(); |
|||
} |
|||
|
|||
protected override void BeforeAddApplication(IServiceCollection services) |
|||
{ |
|||
services.AddStaticDaprClientProxies( |
|||
typeof(AbpDaprTestModule).Assembly, |
|||
"TestDapr"); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Get_Result_Items_Count_Should_5() |
|||
{ |
|||
var result = await _service.GetAsync(); |
|||
|
|||
result.Items.Count.ShouldBe(5); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Get_Wraped_Object() |
|||
{ |
|||
var result = await _service.GetWrapedAsync("Test"); |
|||
|
|||
result.Name.ShouldBe("Test"); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Update_Result_Value_Should_Value_Updated_1() |
|||
{ |
|||
var result = await _service.UpdateAsync(1); |
|||
|
|||
result.Value.ShouldBe("value:updated:1"); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue