I've read a good deal about how HttpClient instances should be reused as much as possible, perhaps even throughout application lifecycle. For completeness sake, here are a couple of the resources that I'm basing my statements on:
- Do HttpClient and HttpClientHandler have to be disposed?
- You're Using HttpClient Wrong and it is Destabilizing Your Software
- What is the overhead of creating a new HttpClient per call in a WebAPI client?
I have a couple of questions regarding this:
- How do I create an application-scoped instance of HttpClient in ASP.NET MVC to be shared among all requests? Let's assume there is no IoC container in picture, so I can't just bind it in Singleton scope with container-name-here and call it a day. How would I do it "manually?"
- Also, the web service I'm interacting with requires a new authorization token on each request, so even if come up with a way to do #1 above, how do I supply a new authorization header on every request, so that it doesn't collide with potential multiple concurrent requests (coming from different users and whatnot)? My understanding is that HttpClient is fairly thread-safe itself, when it comes to GetAsync and other methods, but setting DefaultAuthorizationHeaders doesn't seem thread-safe to me, is it?
- How do I keep it unit-testable?
This is how my in-progress code looks like so far (in a somewhat simplified form for brevity here):
public class MyHttpClientWrapper : IDisposable
{
    private readonly HttpClient _httpClient;
    private readonly TokenManager _tokenManager;
    public HttpServiceClient(HttpClient httpClient, TokenManager tokenManager)
    {
        _httpClient = httpClient;
        _tokenManager = tokenManager;
        _httpClient.BaseAddress = new Uri("https://someapp/api/");
        _httpClient.DefaultRequestHeaders.Accept.Add(new 
            MediaTypeWithQualityHeaderValue("application/json"));
    }
    public string GetDataByQuery(string query)
    {
        _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
            "amx", _tokenManager.GetNewAuthorizationCode());
        var response = _httpClient.GetAsync(query).Result;
        return response.Content.ReadAsStringAsync().Result;
    }
    public void Dispose()
    {
        HttpClient?.Dispose();
    }
}
Side note: I am using dependency injection here, but not necessarily an IoC container (for the reasons irrelevant to this discussion).
 
    