1
votes

In a web-request I want to do a call to another server using Microsoft HttpClient. I am using MVC4 (hosted in IIS), and castle-windsor as IOC-container. I read that the HttpClient is designed to live during serveral calls, and my question is how I should implement this.

I come up with a few options:

  1. Ignore the fact that HttpClient is designed for multiple calls, and create a new one each time i need one.
  2. Create a Singleton(lifestyle in castle) object which stores the HttpClient between calls. Are there any risks with this? Will the performace be bad, if multiple web-request is using the same HTTP-client?

Are there any better pattern to do this?

2

2 Answers

2
votes

I would use LifestyleTransient to create a new one for each request. That's safest when you're not sure that the class can function as a singleton.

It's also not a bad idea to depend on an abstraction (an interface) rather than on the HttpClient directly unless you're certain that the class would never be used apart from making HTTP requests. Even then it may make unit testing easier. That's one of the big benefits of using Windsor or another DI container. Otherwise there's not much benefit over just instantiating an HttpClient directly in your class.


Update. I did some looking and found this answer indicating that an HttpClient should be reused for a given API. It's highly upvoted and I don't see any dissent from experience (or otherwise) so I'm going to reference it when doing some near-term development.

I would implement this by defining a strongly-typed client class that implements an interface, and then depending on the interface in my classes (not directly on the client.) Then Windsor can create the class for an interface and maintain it as a singleton.

0
votes

By default if you create a new instance of HttpClient for each call, then each call will create a new TCP connection, and this will cause latency and reduced throughput. If you want to have a new HttpClient instance because it's got per-call data on it, then you can have a singleton HttpClientHandler, pass it to the HttpClient ctor, and that will share the TCP connections across the HttpClient instances.

Scott, here are three approaches we have used that work. I hope this helps, I'm new to stackoverflow so can't post more than two links apparently.

1) Just have a static/singleton HttpClient, and pass any per-call headers with HttpRequestMessage as described here

2) Have a static/singleton WebRequest|HttpClientHandler, and pass that to the HttpClient ctor with disposeHandler set to false.

3) In some cases, we had a DelegatingHandler instrumentation library that needed to be disposed after each HttpClient call. So we created a WebRequestHandler that does nothing in Dispose() as below, passed that to the DelegatingHandler ctor, and then passed the DelegatingHandler to the HttpClient ctor with disposeHandler set to false.

public class LongLivedWebRequestHandler : WebRequestHandler
{
    public override void Dispose()
    {
        // Do nothing...
    }
}