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?
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.
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.
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.
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.
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 invoke
d 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
When using AddScoped, it's by design that the object will have its lifetime associated with the Request.
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.
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