/// <summary>
        /// Build default circuit breaker, wait and retry and Timeout policy.
        /// </summary>
        /// <param name="transientPolicySettings">retry,timeout and circuit breaker settings.</param>
        /// <returns>policy wrapper.</returns>
        public virtual PolicyWrap <HttpResponseMessage> GetDefaultPolicy(TransientPolicySettings transientPolicySettings)
        {
            //Time out policy to set Http Client request timeout.
            TimeoutPolicy timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromSeconds(transientPolicySettings.HttpTimeOut), timeoutStrategy: TimeoutStrategy.Pessimistic, TimeOutHandler);
            //If http client requiest fails, it will be retried.
            IAsyncPolicy <HttpResponseMessage> retryPolicy = Policy.HandleResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode)
                                                             .Or <HttpRequestException>()
                                                             .WaitAndRetryAsync(transientPolicySettings.RetryAttempts, retryafter => TimeSpan.FromSeconds(Math.Pow(2, retryafter) / 2), OnRetry);
            //Circuit breaker to fail fast.
            IAsyncPolicy <HttpResponseMessage> cb = HttpPolicyExtensions
                                                    .HandleTransientHttpError()
                                                    .AdvancedCircuitBreakerAsync(
                transientPolicySettings.CircuitBreakerSettings.FailureThreshold,
                TimeSpan.FromSeconds(transientPolicySettings.CircuitBreakerSettings.SamplingDuration),
                transientPolicySettings.CircuitBreakerSettings.MinimumThroughput,
                TimeSpan.FromSeconds(transientPolicySettings.CircuitBreakerSettings.DurationOfBreak),
                OnBreak,
                OnReset,
                OnHalfOpen);

            //above policies are wrapped.
            return(timeoutPolicy.WrapAsync(retryPolicy.WrapAsync(cb)));
        }
        /// <summary>
        /// Register instance in DI.
        /// </summary>
        /// <typeparam name="TClient">Interface implemented by a type.</typeparam>
        /// <typeparam name="TImplementation">A type implements TClient interface.</typeparam>
        /// <param name="services">instance of IServiceCollection.</param>
        /// <param name="transientPolicySettings">transient poicy settings.</param>
        public static void RegisterInstace <TClient, TImplementation>(this IServiceCollection services, TransientPolicySettings transientPolicySettings)
            where TClient : class
            where TImplementation : class, TClient
        {
            PolicyBuilder policyBuilder = new PolicyBuilder();
            var           defaultPolicy = policyBuilder.GetDefaultPolicy(transientPolicySettings);

            services.AddHttpClient <TClient, TImplementation>()
            .AddPolicyHandler(t => { return(defaultPolicy); })
            .CorrelateRequests("X-Correlation-ID")
            .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler()
            {
                AllowAutoRedirect      = false,
                AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
            });
        }