Disposing resources at the end of Web API request

Sometimes you have resources in your code that are implementing IDisposable, and that you’d like them to be disposed only at the end of the HTTP request. I have seen a solution to this problem rolled out by hand in a few code bases in the past – but in fact this feature is already built into Web API, which I don’t think a lot of people are aware of.

Let’s have a quick look.


ASP.NET Web API contains an extension method for HttpRequestMessage that’s called RegisterForDispose – which allows you to pass in a single instance or a collection of instances of IDisposable.

What happens under the hood, is that Web API will simply store those object references in the properties dictionary of the request message (under HttpPropertyKeys.DisposableRequestResourcesKey key), and at the end of the Web API request lifetime, will iterate through those objects and call Dispose on them. This is the responsibility of the Web API host, so each of the existing hosting layers – Web Host (“classic” ASP.NET), self host (WCF based) and OWIN host (the Katana adapter) is explicitly implementing this feature. It is guaranteed to happen (for example, the Katana adapter uses a try/catch block around the entire Web API pipeline and performs the disposal in finally.

As a result you can do things like the code below. Imagine a message handler that opens a stream, writes to it, then saves the stream into request properties (so that other Web API components such as other message handlers, filters, controllers etc can use it too):

You don’t have to use a using statement here, as registering for disposal using Web API resource tracking feature will ensure that the stream writer is disposed of at the end of the request lifetime. This is very convenient, as other components during the HTTP request, can share the same resource.

It is also worth adding that resource tracking is also used if you ever use Web API GetDependencyScope feature – which allows you to resolve services from the registered dependency resolver:

In the above case, the instance of IMyService will be registered for disposal at the end of Web API request.

One final note – at any time you can also take a peek into the resources currently registered for disposal, using a GetResourcesForDisposal extension method on HttpRequestMessage.

  • Funbit

    Thank you for the article.

    By the way, I think you should call RegisterForDispose before WriteLineAsync, otherwise it is possible to have a leak if WriteLineAsync or request.Properties fail with an exception.

    • http://www.strathweb.com/ Filip W

      thanks great point!

  • http://www.adamralph.com/ adamralph

    Nice. This reminds me of xBehave.net’s support for object disposal – https://github.com/xbehave/xbehave.net/wiki/Object-disposal

    I guess there could be a similar extension method for this (perhaps even in the same namespace as HttpRequestMessage):

    public static T RegisterForDispose(this T disposable, HttpRequestMessage request)
    where T : IDisposable
    return disposable;

    to allow:

    var writer = new StreamWriter("c:\file.txt", true).RegisterForDispose(request);

    which would encourage people to register the object immediately, more closely emulating a using block.

  • Nils Schiwek

    But what exactly is the benefit regarding the use of using? Or is it an alternative approach?

  • twomm

    That is quite nice.
    However, makes things a bit harder to unit test, if the pipeline is not executed. Do you have any advice on that?