Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to free resources and dispose injected service in ASP.NET 5/Core by the end of request?

I have a service which is injected into a controller using the ASP.NET Core's default Dependency Injection Container:

public class FooBarService : IDisposable {
    public void Dispose() { ... }
}

services.AddScoped<FooBarService>();

This creates one instance per request. How to ensure that the framework would dispose the FooBarService instance by the end of each request, without relying on destructors and garbage collection?

like image 245
x2bool Avatar asked Mar 08 '16 16:03

x2bool


People also ask

How do you dispose of resources using dependency injection?

When you make it explicit, you've got basically two options: 1. Configure the DI to return transient objects and dispose these objects yourself. 2. Configure a factory and instruct the factory to create new instances.

How do you dispose of an object in .NET Core?

Another approach to dispose IDisposable objects automatically is by using the built-in IoC (inversion of control) container in ASP.NET Core. You can take advantage of either Transient, Scoped, or Singleton instances to created services and add them to the built-in IoC container.

Are transient services disposed?

Disposable transient services are captured by the container for disposal. This can turn into a memory leak if resolved from the top-level container. Enable scope validation to make sure the app doesn't have singletons that capture scoped services.

How do you override a dispose method in C#?

These classes need to dispose of these objects. I created a virtual Dispose method in the base ScreenObject base class and then implemented an override Dispose method in each of the derived classes that hold onto unmanaged resources.


3 Answers

Like the all other DI containers, it will dispose IDisposable instances for you with respecting life time of instance.

In your stuation, if instance is registered as Scoped (Instance Per Request). It will dispose this instance after request is completed.

Edit: In official documents they don't mention this. So Let's check source code to be sure:

When a scope is created, ServiceScopeFactory returns a new ServiceScope which is depended with ServiceProvider and disposable.

ServiceProvider has private List<IDisposable> _transientDisposables; which keeps disposable services when TransientCallSite is invoked in CaptureDisposable method. Also ServiceProvider has private readonly Dictionary<IService, object> _resolvedServices = new Dictionary<IService, object>(); which keeps all services for Scoped.

When liftime/scope finishes, the ServiceScope is disposed. Then it disposes ServiceProvider which disposes all _transientDisposables and then it checks _resolvedServices and disposes disposable services in the dictionary in ServiceProvider.

Edit(13.06.2017): They mention in official documents now. Service Lifetimes

like image 176
Erkan Demirel Avatar answered Oct 13 '22 01:10

Erkan Demirel


When using AddScoped, it's by design that the object will have its lifetime associated with the Request.

like image 44
Matias Quaranta Avatar answered Oct 13 '22 02:10

Matias Quaranta


I see no one mentioned this yet, but besides implementing IDisposable in your type, you can also use {HttpContext}.Response.RegisterForDispose(objectToDispose). Typically this is used to register an object at the start of a request (such as a controller action) to be disposed when the request ends.

like image 4
James Wilkins Avatar answered Oct 13 '22 02:10

James Wilkins