-
Notifications
You must be signed in to change notification settings - Fork 446
/
Copy pathDefaultApiActionInvoker.cs
148 lines (133 loc) · 5.06 KB
/
DefaultApiActionInvoker.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using System;
using System.Diagnostics;
using System.Net.Http;
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;
using WebApiClientCore.Exceptions;
using WebApiClientCore.Implementations.Tasks;
namespace WebApiClientCore.Implementations
{
/// <summary>
/// 表示Action执行器
/// </summary>
/// <typeparam name="TResult"></typeparam>
[DebuggerDisplay("Member = {ActionDescriptor.Member}")]
public class DefaultApiActionInvoker<TResult> : ApiActionInvoker, IITaskReturnConvertable
{
/// <summary>
/// 获取Action描述
/// </summary>
public override ApiActionDescriptor ActionDescriptor { get; }
/// <summary>
/// Action执行器
/// </summary>
/// <param name="actionDescriptor"></param>
public DefaultApiActionInvoker(ApiActionDescriptor actionDescriptor)
{
this.ActionDescriptor = actionDescriptor;
}
/// <summary>
/// 转换为ITask返回声明包装的Action执行器
/// </summary>
/// <returns></returns>
public ApiActionInvoker ToITaskReturnActionInvoker()
{
return new ITaskReturnActionInvoker(this);
}
/// <summary>
/// 执行Action
/// </summary>
/// <param name="context">上下文</param>
/// <param name="arguments">参数值</param>
/// <returns></returns>
public sealed override object Invoke(HttpClientContext context, object?[] arguments)
{
return this.InvokeAsync(context, arguments);
}
/// <summary>
/// 执行Action
/// </summary>
/// <param name="context">上下文</param>
/// <param name="arguments">参数值</param>
/// <returns></returns>
public virtual async Task<TResult> InvokeAsync(HttpClientContext context, object?[] arguments)
{
try
{
var requiredUri = context.HttpApiOptions.HttpHost ?? context.HttpClient.BaseAddress;
var useDefaultUserAgent = context.HttpApiOptions.UseDefaultUserAgent;
using var requestMessage = new HttpApiRequestMessageImpl(requiredUri, useDefaultUserAgent);
var httpContext = new HttpContext(context, requestMessage);
var requestContext = new ApiRequestContext(httpContext, this.ActionDescriptor, arguments, new DefaultDataCollection());
return await InvokeAsync(requestContext).ConfigureAwait(false);
}
catch (HttpRequestException)
{
throw;
}
catch (Exception ex)
{
#if NET5_0_OR_GREATER
if (ex is IStatusCodeException exception)
{
throw new HttpRequestException(ex.Message, ex, exception.GetStatusCode());
}
#endif
throw new HttpRequestException(ex.Message, ex);
}
}
/// <summary>
/// 执行Api方法
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
private static async Task<TResult> InvokeAsync(ApiRequestContext request)
{
#nullable disable
var response = await ApiRequestExecutor.ExecuteAsync(request).ConfigureAwait(false);
if (response.ResultStatus == ResultStatus.HasResult)
{
return (TResult)response.Result;
}
if (response.ResultStatus == ResultStatus.HasException)
{
ExceptionDispatchInfo.Capture(response.Exception).Throw();
}
throw new ApiReturnNotSupportedException(response);
#nullable enable
}
/// <summary>
/// 表示ITask返回声明的Action执行器
/// </summary>
[DebuggerDisplay("Member = {ActionDescriptor.Member}")]
private class ITaskReturnActionInvoker : ApiActionInvoker
{
/// <summary>
/// Api执行器
/// </summary>
private readonly DefaultApiActionInvoker<TResult> actionInvoker;
/// <summary>
/// 获取Action描述
/// </summary>
public override ApiActionDescriptor ActionDescriptor => this.actionInvoker.ActionDescriptor;
/// <summary>
/// ITask返回声明的Action执行器
/// </summary>
/// <param name="actionInvoker">Action执行器 </param>
public ITaskReturnActionInvoker(DefaultApiActionInvoker<TResult> actionInvoker)
{
this.actionInvoker = actionInvoker;
}
/// <summary>
/// 执行Action
/// </summary>
/// <param name="context">上下文</param>
/// <param name="arguments">参数值</param>
/// <returns></returns>
public override object Invoke(HttpClientContext context, object?[] arguments)
{
return new ActionTask<TResult>(this.actionInvoker, context, arguments);
}
}
}
}