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?
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With