void DetermineReturnTypeInfo(MethodInfo methodInfo) { if (methodInfo.ReturnType.GetTypeInfo().IsGenericType == false) { if (methodInfo.ReturnType != typeof(Task)) { goto bogusMethod; } ReturnType = methodInfo.ReturnType; SerializedReturnType = typeof(void); return; } var genericType = methodInfo.ReturnType.GetGenericTypeDefinition(); if (genericType != typeof(Task <>) && genericType != typeof(IObservable <>)) { goto bogusMethod; } ReturnType = methodInfo.ReturnType; SerializedReturnType = methodInfo.ReturnType.GetGenericArguments()[0]; if (SerializedReturnType.GetTypeInfo().IsGenericType) { SerializedGenericArgument = SerializedReturnType.GetGenericArguments()[0]; } return; bogusMethod: throw new ArgumentException("All REST Methods must return either Task<T> or IObservable<T>"); }
public RestMethodInfo(Type targetInterface, MethodInfo methodInfo, RefitSettings refitSettings = null) { RefitSettings = refitSettings ?? new RefitSettings(); Type = targetInterface; Name = methodInfo.Name; MethodInfo = methodInfo; var hma = methodInfo.GetCustomAttributes(true) .OfType <HttpMethodAttribute>() .First(); HttpMethod = hma.Method; RelativePath = hma.Path; IsMultipart = methodInfo.GetCustomAttributes(true) .OfType <MultipartAttribute>() .Any(); VerifyUrlPathIsSane(RelativePath); DetermineReturnTypeInfo(methodInfo); // Exclude cancellation token parameters from this list var parameterList = methodInfo.GetParameters().Where(p => p.ParameterType != typeof(CancellationToken)).ToList(); ParameterInfoMap = parameterList .Select((parameter, index) => new { index, parameter }) .ToDictionary(x => x.index, x => x.parameter); ParameterMap = BuildParameterMap(RelativePath, parameterList); BodyParameterInfo = FindBodyParameter(parameterList, IsMultipart, hma.Method); Headers = ParseHeaders(methodInfo); HeaderParameterMap = BuildHeaderParameterMap(parameterList); // get names for multipart attachments AttachmentNameMap = new Dictionary <int, Tuple <string, string> >(); if (IsMultipart) { for (var i = 0; i < parameterList.Count; i++) { if (ParameterMap.ContainsKey(i) || HeaderParameterMap.ContainsKey(i)) { continue; } var attachmentName = GetAttachmentNameForParameter(parameterList[i]); if (attachmentName == null) { continue; } AttachmentNameMap[i] = Tuple.Create(attachmentName, GetUrlNameForParameter(parameterList[i]).ToLowerInvariant()); } } QueryParameterMap = new Dictionary <int, string>(); for (var i = 0; i < parameterList.Count; i++) { if (ParameterMap.ContainsKey(i) || HeaderParameterMap.ContainsKey(i) || (BodyParameterInfo != null && BodyParameterInfo.Item3 == i)) { continue; } QueryParameterMap[i] = GetUrlNameForParameter(parameterList[i]); } var ctParams = methodInfo.GetParameters().Where(p => p.ParameterType == typeof(CancellationToken)).ToList(); if (ctParams.Count > 1) { throw new ArgumentException($"Argument list to method \"{methodInfo.Name}\" can only contain a single CancellationToken"); } CancellationToken = ctParams.FirstOrDefault(); IsApiResponse = SerializedReturnType.GetTypeInfo().IsGenericType&& SerializedReturnType.GetGenericTypeDefinition() == typeof(ApiResponse <>); }