From 1c8bee85e43a2f400079b17f5106c0b57a1c7c76 Mon Sep 17 00:00:00 2001 From: Timothy Makkison Date: Tue, 25 Jun 2024 23:11:28 +0100 Subject: [PATCH] feat: refactors, cache attributes, use helper methods --- Refit/RequestBuilderImplementation.cs | 41 +++++++++++++-------------- Refit/RestMethodInfo.cs | 4 +++ 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/Refit/RequestBuilderImplementation.cs b/Refit/RequestBuilderImplementation.cs index cc4d88aef..789b090da 100644 --- a/Refit/RequestBuilderImplementation.cs +++ b/Refit/RequestBuilderImplementation.cs @@ -14,7 +14,8 @@ class RequestBuilderImplementation(RefitSettings? refitSettings = null) partial class RequestBuilderImplementation : IRequestBuilder { - static readonly HashSet BodylessMethods = [HttpMethod.Get, HttpMethod.Head]; + static readonly QueryAttribute DefaultQueryAttribute = new (); + static readonly Uri BaseUri = new Uri("http://api"); readonly Dictionary> interfaceHttpMethods; readonly ConcurrentDictionary< CloseGenericMethodKey, @@ -803,13 +804,12 @@ await content //if header collection, add to request headers if (restMethod.HeaderCollectionParameterMap.Contains(i)) { - var headerCollection = - param as IDictionary - ?? new Dictionary(); - - foreach (var header in headerCollection) + if (param is IDictionary headerCollection) { - headersToAdd[header.Key] = header.Value; + foreach (var header in headerCollection) + { + headersToAdd[header.Key] = header.Value; + } } isParameterMappedToRequest = true; @@ -850,7 +850,7 @@ param as IDictionary || queryAttribute != null ) { - var attr = queryAttribute ?? new QueryAttribute(); + var attr = queryAttribute ?? DefaultQueryAttribute; if (DoNotConvertToQueryMap(param)) { queryParamsToAdd.AddRange( @@ -924,7 +924,7 @@ param as IDictionary // We could have content headers, so we need to make // sure we have an HttpContent object to add them to, // provided the HttpClient will allow it for the method - if (ret.Content == null && !BodylessMethods.Contains(ret.Method)) + if (ret.Content == null && !IsBodyless(ret.Method)) ret.Content = new ByteArrayContent(Array.Empty()); foreach (var header in headersToAdd) @@ -979,7 +979,7 @@ param as IDictionary // NB: The URI methods in .NET are dumb. Also, we do this // UriBuilder business so that we preserve any hardcoded query // parameters as well as add the parameterized ones. - var uri = new UriBuilder(new Uri(new Uri("http://api"), urlTarget)); + var uri = new UriBuilder(new Uri(BaseUri, urlTarget)); ParseExistingQueryString(uri, queryParamsToAdd); if (queryParamsToAdd.Count != 0) @@ -991,11 +991,8 @@ param as IDictionary uri.Query = null; } - var uriFormat = - restMethod.MethodInfo.GetCustomAttribute()?.UriFormat - ?? UriFormat.UriEscaped; ret.RequestUri = new Uri( - uri.Uri.GetComponents(UriComponents.PathAndQuery, uriFormat), + uri.Uri.GetComponents(UriComponents.PathAndQuery, restMethod.QueryUriFormat), UriKind.Relative ); return ret; @@ -1064,13 +1061,13 @@ var value in ParseEnumerableQueryParameterValue( default: var delimiter = - collectionFormat == CollectionFormat.Ssv - ? " " - : collectionFormat == CollectionFormat.Tsv - ? "\t" - : collectionFormat == CollectionFormat.Pipes - ? "|" - : ","; + collectionFormat switch + { + CollectionFormat.Ssv => " ", + CollectionFormat.Tsv => "\t", + CollectionFormat.Pipes => "|", + _ => "," + }; // Missing a "default" clause was preventing the collection from serializing at all, as it was hitting "continue" thus causing an off-by-one error var formattedValues = paramValues @@ -1304,5 +1301,7 @@ static void SetHeader(HttpRequestMessage request, string name, string? value) request.Content.Headers.TryAddWithoutValidation(name, value); } } + + static bool IsBodyless(HttpMethod method) => method == HttpMethod.Get || method == HttpMethod.Head; } } diff --git a/Refit/RestMethodInfo.cs b/Refit/RestMethodInfo.cs index 2139fa8e3..cb2ef6afa 100644 --- a/Refit/RestMethodInfo.cs +++ b/Refit/RestMethodInfo.cs @@ -35,6 +35,7 @@ internal class RestMethodInfoInternal public bool IsMultipart { get; private set; } public string MultipartBoundary { get; private set; } public ParameterInfo? CancellationToken { get; set; } + public UriFormat QueryUriFormat { get; set; } public Dictionary Headers { get; set; } public Dictionary HeaderParameterMap { get; set; } public ISet HeaderCollectionParameterMap { get; set; } @@ -161,6 +162,9 @@ public RestMethodInfoInternal( CancellationToken = ctParam; + QueryUriFormat = methodInfo.GetCustomAttribute()?.UriFormat + ?? UriFormat.UriEscaped; + IsApiResponse = ReturnResultType!.GetTypeInfo().IsGenericType && (