Reputation: 1013
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?
Upvotes: 4
Views: 2162
Reputation: 5125
You can use the nuget package Microsoft.AspNet.WebApi.Client which has HttpClientFactory with below two factory methods. Wiring up the InnerHandler
s 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)
Upvotes: 1
Reputation: 22829
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
Upvotes: 5