3

I'm just trying to create a simple test where I use DelegateHandlers to instantiate a HttpClient without bringing Asp.net Core packages. I have 2 deletage handlers

  • ThrottlingDelegatingHandler
  • PolicyHttpMessageHandler (from Polly package)

How can I combine both and pass to the HttpClient?

var policy = HttpPolicyExtensions.HandleTransientHttpError().CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
var pollyHandler = new PolicyHttpMessageHandler(policy);
var http = new HttpClient(new ThrottlingDelegatingHandler(MaxParallelism, pollyHandler));

The above gives me an error: System.InvalidOperationException : The inner handler has not been assigned.

The PolicyHttpMessageHandler does not have a constructor where I can pass the innerHandler.

How can I accomplish this?

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
JobaDiniz
  • 862
  • 1
  • 14
  • 32

2 Answers2

5

You have to set the InnerHandler in your most inner handler to HttpClientHandler like this:

var policy = HttpPolicyExtensions.HandleTransientHttpError().CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
var pollyHandler = new PolicyHttpMessageHandler(policy);

//New line
pollyHandler.InnerHandler = new HttpClientHandler();

var http = new HttpClient(new ThrottlingDelegatingHandler(MaxParallelism, pollyHandler));

You basically have to set the next handler in the pipeline.


For reference: this is how HttpClient is constructed if no handler is specified

#region Constructors

public HttpClient() : this(new HttpClientHandler())
{
}

public HttpClient(HttpMessageHandler handler) : this(handler, true)
{
}

public HttpClient(HttpMessageHandler handler, bool disposeHandler) : base(handler, disposeHandler)
{
    _timeout = s_defaultTimeout;
    _maxResponseContentBufferSize = HttpContent.MaxBufferSize;
    _pendingRequestsCts = new CancellationTokenSource();
}

#endregion Constructors

Where the base is the HttpMessageInvoker class

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
1

You can use the nuget package Microsoft.AspNet.WebApi.Client which has HttpClientFactory with below two factory methods. Wiring up the InnerHandlers when one has to deal with multiple delegatingHandlers becomes unwieldy; it's best done with some code. If you don't want a nuget dependency, it's not difficult to handroll your own Create() implementations.

HttpClient Create(params DelegatingHandler[] handlers)
HttpClient Create(HttpMessageHandler innerHandler, params DelegatingHandler[] handlers)
hIpPy
  • 4,649
  • 6
  • 51
  • 65