|
12 | 12 | using FMData.Rest.Responses; |
13 | 13 | using Newtonsoft.Json; |
14 | 14 | using Newtonsoft.Json.Linq; |
| 15 | +#if NETSTANDARD2_0_OR_GREATER || NET6_0_OR_GREATER |
| 16 | +using Microsoft.Extensions.DependencyInjection; |
| 17 | +#endif |
15 | 18 |
|
16 | 19 | namespace FMData.Rest |
17 | 20 | { |
@@ -55,7 +58,40 @@ public class FileMakerRestClient : FileMakerApiClientBase, IFileMakerRestClient |
55 | 58 | private readonly bool _useNewClientForContainers = false; |
56 | 59 | private readonly string _targetVersion = "v1"; |
57 | 60 |
|
| 61 | +#if NETSTANDARD2_0_OR_GREATER || NET6_0_OR_GREATER |
| 62 | + private readonly IHttpClientFactory _httpClientFactory; |
| 63 | +#endif |
| 64 | + |
58 | 65 | #region Constructors |
| 66 | + |
| 67 | +#if NETSTANDARD2_0_OR_GREATER || NET6_0_OR_GREATER |
| 68 | + /// <summary> |
| 69 | + /// FM Data Constructor with IHttpClientFactory and ConnectionInfo. |
| 70 | + /// Uses the factory to create the primary HttpClient and for container downloads. |
| 71 | + /// </summary> |
| 72 | + /// <param name="httpClientFactory">The IHttpClientFactory to use for creating HttpClient instances.</param> |
| 73 | + /// <param name="conn">The connection information for FMS.</param> |
| 74 | + public FileMakerRestClient( |
| 75 | + IHttpClientFactory httpClientFactory, |
| 76 | + ConnectionInfo conn) |
| 77 | + : this(httpClientFactory, new DefaultAuthTokenProvider(conn)) |
| 78 | + { } |
| 79 | + |
| 80 | + /// <summary> |
| 81 | + /// FM Data Constructor with IHttpClientFactory and an authentication provider. |
| 82 | + /// Uses the factory to create the primary HttpClient and for container downloads. |
| 83 | + /// </summary> |
| 84 | + /// <param name="httpClientFactory">The IHttpClientFactory to use for creating HttpClient instances.</param> |
| 85 | + /// <param name="authTokenProvider">Authentication provider.</param> |
| 86 | + public FileMakerRestClient( |
| 87 | + IHttpClientFactory httpClientFactory, |
| 88 | + IAuthTokenProvider authTokenProvider) |
| 89 | + : this(httpClientFactory.CreateClient(), authTokenProvider, false) |
| 90 | + { |
| 91 | + _httpClientFactory = httpClientFactory; |
| 92 | + } |
| 93 | +#endif |
| 94 | + |
59 | 95 | /// <summary> |
60 | 96 | /// Create a FileMakerRestClient with a new instance of HttpClient. |
61 | 97 | /// </summary> |
@@ -1137,11 +1173,20 @@ protected override async Task<byte[]> GetContainerOnClient(string containerEndPo |
1137 | 1173 | // build the request message |
1138 | 1174 | var requestMessage = new HttpRequestMessage(HttpMethod.Get, containerEndPoint); |
1139 | 1175 |
|
| 1176 | + // determine the client to use for container downloads |
| 1177 | +#if NETSTANDARD2_0_OR_GREATER || NET6_0_OR_GREATER |
| 1178 | + // prefer factory-created clients when available (proper handler pooling) |
| 1179 | + var client = _httpClientFactory != null |
| 1180 | + ? _httpClientFactory.CreateClient() |
| 1181 | + : (_useNewClientForContainers |
| 1182 | + ? new HttpClient(new HttpClientHandler() { CookieContainer = new CookieContainer() }) |
| 1183 | + : Client); |
| 1184 | +#else |
1140 | 1185 | // if we're supposed to use new clients for processing containers or not |
1141 | | - var client = _useNewClientForContainers ? new HttpClient(new HttpClientHandler() |
1142 | | - { |
1143 | | - CookieContainer = new CookieContainer() |
1144 | | - }) : Client; |
| 1186 | + var client = _useNewClientForContainers |
| 1187 | + ? new HttpClient(new HttpClientHandler() { CookieContainer = new CookieContainer() }) |
| 1188 | + : Client; |
| 1189 | +#endif |
1145 | 1190 |
|
1146 | 1191 | // send the request out |
1147 | 1192 | var data = await client.SendAsync(requestMessage).ConfigureAwait(false); |
@@ -1214,18 +1259,12 @@ private async Task<HttpResponseMessage> RetryOnUnauthorizedAsync(Func<Task<HttpR |
1214 | 1259 | return response; |
1215 | 1260 | } |
1216 | 1261 |
|
1217 | | - /// <summary> |
1218 | | - /// Converts a JToken instance and maps it to the generic type. |
1219 | | - /// </summary> |
1220 | | - /// <typeparam name="T"></typeparam> |
1221 | | - /// <param name="fmId">FileMaker Record Id map function.</param> |
1222 | | - /// <param name="modId">Modification Id map function.</param> |
1223 | | - /// <param name="input">JSON.NET JToken instance from Data Api Response.</param> |
1224 | | - /// <returns></returns> |
1225 | 1262 | /// <summary> |
1226 | 1263 | /// Extracts script result fields (including pre-request and pre-sort) from a response JToken. |
1227 | 1264 | /// Handles dotted property names that cannot be mapped via attributes. |
1228 | 1265 | /// </summary> |
| 1266 | + /// <param name="target">The <see cref="ActionResponse"/> to populate with script results.</param> |
| 1267 | + /// <param name="responseToken">JSON.NET JToken from the Data API response body.</param> |
1229 | 1268 | private static void PopulateScriptResults(ActionResponse target, JToken responseToken) |
1230 | 1269 | { |
1231 | 1270 | if (target == null || responseToken == null) return; |
|
0 commit comments