housekeeping: invert `ifs`, use `TryGetValue`, remove unneeded `ToArray` (#1619)
This commit is contained in:
Родитель
2dff048afa
Коммит
3cbe67af36
|
@ -48,78 +48,76 @@ namespace Refit
|
|||
|
||||
lock (PropertyCache)
|
||||
{
|
||||
if (!PropertyCache.ContainsKey(type))
|
||||
if (!PropertyCache.TryGetValue(type, out var properties))
|
||||
{
|
||||
PropertyCache[type] = GetProperties(type);
|
||||
properties = GetProperties(type);
|
||||
PropertyCache[type] = properties;
|
||||
}
|
||||
|
||||
foreach (var property in PropertyCache[type])
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var value = property.GetValue(source, null);
|
||||
if (value != null)
|
||||
if (value == null)
|
||||
continue;
|
||||
|
||||
var fieldName = GetFieldNameForProperty(property);
|
||||
|
||||
// see if there's a query attribute
|
||||
var attrib = property.GetCustomAttribute<QueryAttribute>(true);
|
||||
|
||||
if (value is not IEnumerable enumerable)
|
||||
{
|
||||
var fieldName = GetFieldNameForProperty(property);
|
||||
Add(
|
||||
fieldName,
|
||||
settings.FormUrlEncodedParameterFormatter.Format(value, attrib?.Format)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// see if there's a query attribute
|
||||
var attrib = property.GetCustomAttribute<QueryAttribute>(true);
|
||||
var collectionFormat =
|
||||
attrib != null && attrib.IsCollectionFormatSpecified
|
||||
? attrib.CollectionFormat
|
||||
: settings.CollectionFormat;
|
||||
|
||||
if (value is IEnumerable enumerable)
|
||||
{
|
||||
var collectionFormat =
|
||||
attrib != null && attrib.IsCollectionFormatSpecified
|
||||
? attrib.CollectionFormat
|
||||
: settings.CollectionFormat;
|
||||
|
||||
switch (collectionFormat)
|
||||
switch (collectionFormat)
|
||||
{
|
||||
case CollectionFormat.Multi:
|
||||
foreach (var item in enumerable)
|
||||
{
|
||||
case CollectionFormat.Multi:
|
||||
foreach (var item in enumerable)
|
||||
{
|
||||
Add(
|
||||
fieldName,
|
||||
settings.FormUrlEncodedParameterFormatter.Format(
|
||||
item,
|
||||
attrib?.Format
|
||||
)
|
||||
);
|
||||
}
|
||||
break;
|
||||
case CollectionFormat.Csv:
|
||||
case CollectionFormat.Ssv:
|
||||
case CollectionFormat.Tsv:
|
||||
case CollectionFormat.Pipes:
|
||||
var delimiter = collectionFormat switch
|
||||
{
|
||||
CollectionFormat.Csv => ",",
|
||||
CollectionFormat.Ssv => " ",
|
||||
CollectionFormat.Tsv => "\t",
|
||||
_ => "|"
|
||||
};
|
||||
Add(
|
||||
fieldName,
|
||||
settings.FormUrlEncodedParameterFormatter.Format(
|
||||
item,
|
||||
attrib?.Format
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
var formattedValues = enumerable
|
||||
.Cast<object>()
|
||||
.Select(
|
||||
v =>
|
||||
settings.FormUrlEncodedParameterFormatter.Format(
|
||||
v,
|
||||
attrib?.Format
|
||||
)
|
||||
);
|
||||
Add(fieldName, string.Join(delimiter, formattedValues));
|
||||
break;
|
||||
default:
|
||||
Add(
|
||||
fieldName,
|
||||
break;
|
||||
case CollectionFormat.Csv:
|
||||
case CollectionFormat.Ssv:
|
||||
case CollectionFormat.Tsv:
|
||||
case CollectionFormat.Pipes:
|
||||
var delimiter = collectionFormat switch
|
||||
{
|
||||
CollectionFormat.Csv => ",",
|
||||
CollectionFormat.Ssv => " ",
|
||||
CollectionFormat.Tsv => "\t",
|
||||
_ => "|"
|
||||
};
|
||||
|
||||
var formattedValues = enumerable
|
||||
.Cast<object>()
|
||||
.Select(
|
||||
v =>
|
||||
settings.FormUrlEncodedParameterFormatter.Format(
|
||||
value,
|
||||
v,
|
||||
attrib?.Format
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
);
|
||||
Add(fieldName, string.Join(delimiter, formattedValues));
|
||||
break;
|
||||
default:
|
||||
Add(
|
||||
fieldName,
|
||||
settings.FormUrlEncodedParameterFormatter.Format(
|
||||
|
@ -127,7 +125,7 @@ namespace Refit
|
|||
attrib?.Format
|
||||
)
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace Refit
|
|||
|
||||
partial class RequestBuilderImplementation : IRequestBuilder
|
||||
{
|
||||
static readonly ISet<HttpMethod> BodylessMethods = new HashSet<HttpMethod>
|
||||
static readonly HashSet<HttpMethod> BodylessMethods = new HashSet<HttpMethod>
|
||||
{
|
||||
HttpMethod.Get,
|
||||
HttpMethod.Head
|
||||
|
@ -74,16 +74,17 @@ namespace Refit
|
|||
{
|
||||
var attrs = methodInfo.GetCustomAttributes(true);
|
||||
var hasHttpMethod = attrs.OfType<HttpMethodAttribute>().Any();
|
||||
if (hasHttpMethod)
|
||||
{
|
||||
if (!methods.ContainsKey(methodInfo.Name))
|
||||
{
|
||||
methods.Add(methodInfo.Name, new List<RestMethodInfoInternal>());
|
||||
}
|
||||
if (!hasHttpMethod)
|
||||
continue;
|
||||
|
||||
var restinfo = new RestMethodInfoInternal(interfaceType, methodInfo, settings);
|
||||
methods[methodInfo.Name].Add(restinfo);
|
||||
if (!methods.TryGetValue(methodInfo.Name, out var methodInfoInternals))
|
||||
{
|
||||
methodInfoInternals = new List<RestMethodInfoInternal>();
|
||||
methods.Add(methodInfo.Name, methodInfoInternals);
|
||||
}
|
||||
|
||||
var restinfo = new RestMethodInfoInternal(interfaceType, methodInfo, settings);
|
||||
methodInfoInternals.Add(restinfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,64 +94,62 @@ namespace Refit
|
|||
Type[]? genericArgumentTypes
|
||||
)
|
||||
{
|
||||
if (interfaceHttpMethods.TryGetValue(key, out var httpMethods))
|
||||
{
|
||||
if (parameterTypes == null)
|
||||
{
|
||||
if (httpMethods.Count > 1)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"MethodName exists more than once, '{nameof(parameterTypes)}' mut be defined"
|
||||
);
|
||||
}
|
||||
return CloseGenericMethodIfNeeded(httpMethods[0], genericArgumentTypes);
|
||||
}
|
||||
|
||||
var isGeneric = genericArgumentTypes?.Length > 0;
|
||||
|
||||
var possibleMethodsList = httpMethods.Where(
|
||||
method => method.MethodInfo.GetParameters().Length == parameterTypes.Length
|
||||
);
|
||||
|
||||
// If it's a generic method, add that filter
|
||||
if (isGeneric)
|
||||
possibleMethodsList = possibleMethodsList.Where(
|
||||
method =>
|
||||
method.MethodInfo.IsGenericMethod
|
||||
&& method.MethodInfo.GetGenericArguments().Length
|
||||
== genericArgumentTypes!.Length
|
||||
);
|
||||
else // exclude generic methods
|
||||
possibleMethodsList = possibleMethodsList.Where(
|
||||
method => !method.MethodInfo.IsGenericMethod
|
||||
);
|
||||
|
||||
var possibleMethods = possibleMethodsList.ToList();
|
||||
|
||||
if (possibleMethods.Count == 1)
|
||||
return CloseGenericMethodIfNeeded(possibleMethods[0], genericArgumentTypes);
|
||||
|
||||
var parameterTypesArray = parameterTypes.ToArray();
|
||||
foreach (var method in possibleMethods)
|
||||
{
|
||||
var match = method.MethodInfo
|
||||
.GetParameters()
|
||||
.Select(p => p.ParameterType)
|
||||
.SequenceEqual(parameterTypesArray);
|
||||
if (match)
|
||||
{
|
||||
return CloseGenericMethodIfNeeded(method, genericArgumentTypes);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception("No suitable Method found...");
|
||||
}
|
||||
else
|
||||
if (!interfaceHttpMethods.TryGetValue(key, out var httpMethods))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Method must be defined and have an HTTP Method attribute"
|
||||
);
|
||||
}
|
||||
|
||||
if (parameterTypes == null)
|
||||
{
|
||||
if (httpMethods.Count > 1)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"MethodName exists more than once, '{nameof(parameterTypes)}' mut be defined"
|
||||
);
|
||||
}
|
||||
|
||||
return CloseGenericMethodIfNeeded(httpMethods[0], genericArgumentTypes);
|
||||
}
|
||||
|
||||
var isGeneric = genericArgumentTypes?.Length > 0;
|
||||
|
||||
var possibleMethodsList = httpMethods.Where(
|
||||
method => method.MethodInfo.GetParameters().Length == parameterTypes.Length
|
||||
);
|
||||
|
||||
// If it's a generic method, add that filter
|
||||
if (isGeneric)
|
||||
possibleMethodsList = possibleMethodsList.Where(
|
||||
method =>
|
||||
method.MethodInfo.IsGenericMethod
|
||||
&& method.MethodInfo.GetGenericArguments().Length
|
||||
== genericArgumentTypes!.Length
|
||||
);
|
||||
else // exclude generic methods
|
||||
possibleMethodsList = possibleMethodsList.Where(
|
||||
method => !method.MethodInfo.IsGenericMethod
|
||||
);
|
||||
|
||||
var possibleMethods = possibleMethodsList.ToList();
|
||||
|
||||
if (possibleMethods.Count == 1)
|
||||
return CloseGenericMethodIfNeeded(possibleMethods[0], genericArgumentTypes);
|
||||
|
||||
foreach (var method in possibleMethods)
|
||||
{
|
||||
var match = method.MethodInfo
|
||||
.GetParameters()
|
||||
.Select(p => p.ParameterType)
|
||||
.SequenceEqual(parameterTypes);
|
||||
if (match)
|
||||
{
|
||||
return CloseGenericMethodIfNeeded(method, genericArgumentTypes);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception("No suitable Method found...");
|
||||
}
|
||||
|
||||
RestMethodInfoInternal CloseGenericMethodIfNeeded(
|
||||
|
@ -487,19 +486,12 @@ namespace Refit
|
|||
if (obj == null)
|
||||
continue;
|
||||
|
||||
if (parameterInfo != null)
|
||||
//if we have a parameter info lets check it to make sure it isn't bound to the path
|
||||
if (parameterInfo is { IsObjectPropertyParameter: true })
|
||||
{
|
||||
//if we have a parameter info lets check it to make sure it isn't bound to the path
|
||||
if (parameterInfo.IsObjectPropertyParameter)
|
||||
if (parameterInfo.ParameterProperties.Any(x => x.PropertyInfo == propertyInfo))
|
||||
{
|
||||
if (
|
||||
parameterInfo.ParameterProperties.Any(
|
||||
x => x.PropertyInfo == propertyInfo
|
||||
)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -511,7 +503,7 @@ namespace Refit
|
|||
|
||||
// Look to see if the property has a Query attribute, and if so, format it accordingly
|
||||
var queryAttribute = propertyInfo.GetCustomAttribute<QueryAttribute>();
|
||||
if (queryAttribute != null && queryAttribute.Format != null)
|
||||
if (queryAttribute is { Format: not null })
|
||||
{
|
||||
obj = settings.FormUrlEncodedParameterFormatter.Format(
|
||||
obj,
|
||||
|
@ -657,9 +649,9 @@ namespace Refit
|
|||
var isParameterMappedToRequest = false;
|
||||
var param = paramList[i];
|
||||
// if part of REST resource URL, substitute it in
|
||||
if (restMethod.ParameterMap.ContainsKey(i))
|
||||
if (restMethod.ParameterMap.TryGetValue(i, out var parameterMapValue))
|
||||
{
|
||||
parameterInfo = restMethod.ParameterMap[i];
|
||||
parameterInfo = parameterMapValue;
|
||||
if (parameterInfo.IsObjectPropertyParameter)
|
||||
{
|
||||
foreach (var propertyInfo in parameterInfo.ParameterProperties)
|
||||
|
@ -684,9 +676,9 @@ namespace Refit
|
|||
{
|
||||
string pattern;
|
||||
string replacement;
|
||||
if (restMethod.ParameterMap[i].Type == ParameterType.RoundTripping)
|
||||
if (parameterMapValue.Type == ParameterType.RoundTripping)
|
||||
{
|
||||
pattern = $@"{{\*\*{restMethod.ParameterMap[i].Name}}}";
|
||||
pattern = $@"{{\*\*{parameterMapValue.Name}}}";
|
||||
var paramValue = (string)param;
|
||||
replacement = string.Join(
|
||||
"/",
|
||||
|
@ -706,7 +698,7 @@ namespace Refit
|
|||
}
|
||||
else
|
||||
{
|
||||
pattern = "{" + restMethod.ParameterMap[i].Name + "}";
|
||||
pattern = "{" + parameterMapValue.Name + "}";
|
||||
replacement = Uri.EscapeDataString(
|
||||
settings.UrlParameterFormatter.Format(
|
||||
param,
|
||||
|
@ -802,9 +794,9 @@ namespace Refit
|
|||
}
|
||||
|
||||
// if header, add to request headers
|
||||
if (restMethod.HeaderParameterMap.ContainsKey(i))
|
||||
if (restMethod.HeaderParameterMap.TryGetValue(i, out var headerParameterValue))
|
||||
{
|
||||
headersToAdd[restMethod.HeaderParameterMap[i]] = param?.ToString();
|
||||
headersToAdd[headerParameterValue] = param?.ToString();
|
||||
isParameterMappedToRequest = true;
|
||||
}
|
||||
|
||||
|
@ -1000,7 +992,7 @@ namespace Refit
|
|||
}
|
||||
}
|
||||
|
||||
if (queryParamsToAdd.Any())
|
||||
if (queryParamsToAdd.Count != 0)
|
||||
{
|
||||
var pairs = queryParamsToAdd
|
||||
.Where(x => x.Key != null && x.Value != null)
|
||||
|
|
Загрузка…
Ссылка в новой задаче