private void AddHeaders(ApiCallCommand <TRequest, TResult> apiRequest, ref HttpRequestMessage request)
 {
     foreach (var item in apiRequest.Headers)
     {
         request.Headers.Add(item.Key, item.Value);
     }
 }
        public async Task <TResult> HandleRequestAsync(ApiCallCommand <TRequest, TResult> apiRequest = null)
        {
            HttpResponseMessage response = new HttpResponseMessage();

            apiRequest = apiRequest ?? ApiRequest;
            if (!ValidateApiCallRequest(apiRequest))
            {
                return(null);
            }
            using (var client = new HttpClient())
            {
                var request = PostRequestAction?.Invoke(apiRequest.RequestObject);

                AddRequestUri(apiRequest, ref request);
                AddHeaders(apiRequest, ref request);

                return(await Retry
                       .WithIncremental(retryCount : 5, initialInterval : TimeSpan.FromSeconds(1),
                                        increment : TimeSpan.FromSeconds(1))
                       .Catch <OperationCanceledException>()
                       .Catch <HttpRequestException>(exception => exception is HttpRequestException && response.StatusCode == HttpStatusCode.RequestTimeout)
                       .ExecuteAction(async() =>
                {
                    response = await client.SendAsync(request);
                    var resultToReturn = PreRequestAction?.Invoke(response);
                    return resultToReturn;
                }));
            }
        }
        private void AddRequestUri(ApiCallCommand <TRequest, TResult> apiRequest, ref HttpRequestMessage request)
        {
            var queryString      = apiRequest.Parameters?.Count > 0 ? $"?{GetParametersString(apiRequest.Parameters)}" : "";
            var subPath          = !String.IsNullOrEmpty(apiRequest.Operation_SubPath) ? $"/{apiRequest.Operation_SubPath}" : "";
            var requestUriString = $"{apiRequest.Endpoint_Uri}/{apiRequest.Endpoint_Version}/{apiRequest.Operation_Path}{subPath}{queryString}";

            request.Method     = new HttpMethod(apiRequest.Operation_Method);
            request.RequestUri = new Uri(requestUriString);
        }
        private bool ValidateApiCallRequest(ApiCallCommand <TRequest, TResult> apiRequest)
        {
            List <ValidationResult> validationResults = new List <ValidationResult>();
            ValidationContext       context           = new ValidationContext(apiRequest.RequestObject);

            Validator.TryValidateObject(apiRequest.RequestObject, context, validationResults);

            return(validationResults.Count == 0);
        }
 public ApiCommandHandler(
     ApiCallCommand <TRequest, TResult> apiRequest,
     Func <TRequest, HttpRequestMessage> postRequestAction = null,
     Func <HttpResponseMessage, TResult> preRequestAction  = null)
 {
     ApiRequest        = apiRequest;
     PostRequestAction = postRequestAction == null
         ? apiRequest.Headers["ContentType"] == "application/json" ? GetPostRequestAction() : GetPostStreamRequestAction()
         : postRequestAction;
     PreRequestAction = preRequestAction == null
         ? GetPreRequestAction() : preRequestAction;
 }