Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dispose of Injected HttpClient

Our MVC application calls a WebAPI action using HttpClient. I decided to inject the HttpClient using StructureMap and override dispose in the controller

public HomeController(HttpClient httpClient)
{
    _httpClient = httpClient;
}

protected override void Dispose(bool disposing)
{
   if (disposing && _httpClient != null)
   {
       _httpClient.Dispose();
   }
   base.Dispose(disposing);
}

The StructureMap ObjectInitialize basically looks like this..

x.For<HttpClient>().Use(() => new HttpClient() { BaseAddress = "my/uri/"});

When I build this, CodeAnalysis complains "Dispose objects before losing scope"and points to the IoC code.

Can I Suppress that, or where do I need to dispose of the HttpClient? I also tried

protected void Application_EndRequest(object sender, EventArgs e)
{
    ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
}

But I still get that rule violation.

like image 246
jlembke Avatar asked Jan 14 '23 11:01

jlembke


2 Answers

Disposing HttpClient cleans up any active Cancellation tokens and any partially complete requests/responses. Under most normal scenarios disposing it will not be essential, although by convention you should. Be aware though that disposing HttpClient will forcibly close the TCP connection.

If your MVC application is making lots of calls to the same server, it might be worth holding onto the HttpClient instance across requests and reusing it. That will avoid you having to re-setup the default request headers each time and it will allow the reuse of the TCP connection.

like image 96
Darrel Miller Avatar answered Jan 22 '23 21:01

Darrel Miller


The object that triggers the creation of an object is normally the one responsible for disposing it as well. In this case the HttpClient is created by Structuremap via the DependencyResolver or ControllerFactory. There is no easy way to dispose transient objects with Structuremap, so you want to minimize the injections of IDisposable objects, especially transient ones. I think that you should put the creation and disposal in a service and inject that to the controller instead.

ReleaseAndDisposeAllHttpScopedObjects will not work in this case since it only disposes objects configured as HttpScoped, that is objects that are kept during the whole http request.

like image 38
PHeiberg Avatar answered Jan 22 '23 19:01

PHeiberg