Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use Request.RegisterForDispose?

For ASP.NET Web API, I've been working on my own implementation of IHttpControllerActivator and am left wondering when (or why?) to use the HttpRequestMessage extension method "RegisterForDispose".

I see examples like this, and I can see the relevance in it, since IHttpController doesn't inherit IDisposable, and an implementation of IHttpController doesn't guarantee its own dispose logic.

public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
    var controller = (IHttpController) _kernel.Get(controllerType);
    request.RegisterForDispose( new Release(()=> _kernel.Release(controller)));
    return controller;
}

But then I see something like this and begin to wonder:

public IHttpController Create(
    HttpRequestMessage request,
    HttpControllerDescriptor controllerDescriptor,
    Type controllerType)
{
    if (controllerType == typeof(RootController))
    {
        var disposableQuery = new DisposableStatusQuery();
        request.RegisterForDispose(disposableQuery);
        return new RootController(disposableQuery);
    }
    return null;
}

In this instance RootController isn't registered for disposal here, presumably because its an ApiController or MVC Controller? - And thus will dispose itself.

The instance of DisposableStatusQuery is registered for disposal since it's a disposable object, but why couldn't the controller dispose of the instance itself? RootController has knowledge of disposableQuery (or rather, it's interface or abstract base), so would know it's disposable.

When would I actually need to use HttpRequestMessage.RegisterForDispose?

like image 796
Snixtor Avatar asked Nov 04 '22 08:11

Snixtor


2 Answers

One scenario I've found it useful for: for a custom ActionFilter.

Because the Attribute is cached/re-used, items within the Attribute shouldn't rely on the controller to be disposed of (to my understanding - and probably with caveats)... so in order to create a custom attribute which isn't tied to a particular controller type/implementation, you can use this technique to clean up your stuff. In my case, it's for an ambient DbContextScope attribute.

like image 105
Nathan Avatar answered Nov 12 '22 20:11

Nathan


RegisterForDispose it's a hook that will be called when the request is disposed. This is often used along with "some" of the dependency injection containers.

For instance, some containers (like Castle.Windsor) by default will track all dependencies that they resolve. This is according to Windsor ReleasePolicy LifecycledComponentsReleasePolicy which states that it will keep track of all components that were created. In other words your garbage collector will not be able to cleanup if your container still tracks your component. Which will result into memory leaks.

So for example when you define your own IHttpControllerActivator to use it with a dependency injection container it is in order to resolve the concrete controller and all its dependencies. At the end of the request you need to release all the created dependencies by the container otherwise you will end with a big memory leak. You have this opportunity doing it with RegisterForDispose

like image 40
Tomasz Jaskuλa Avatar answered Nov 12 '22 21:11

Tomasz Jaskuλa