Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core/5/6 - When exactly does a "Scoped Service" get disposed?

In ASP.NET Core/5/6 you can register a "Scoped Service" with the ServiceCollectionServiceExtensions.AddScoped() method.

In the Microsoft .NET Article Dependency injection in .NET, it states:

In apps that process requests, scoped services are disposed at the end of the request. https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection#scoped

Is their definition of "end of the request" before or after the response (including headers) has been sent?

like image 622
user3163495 Avatar asked Dec 17 '25 21:12

user3163495


1 Answers

Answer: after

After running a test, it looks like scoped services are disposed after the response has finished sending. This is unfortunate, because if the response is a large file, it may take a few seconds to finish sending to the client, and the service will be unnecessarily kept alive (undisposed) that whole time. It would be better if scoped services were disposed before the response begins sending.

Anyway, here's the test I made.

First I created a test IDisposable class that writes to the console whenever it is instantiated and disposed:

public sealed class DisposableTest : IDisposable
{
    public DisposableTest()
    {
        Console.WriteLine("//////////////////// Created");
    }
    private bool Disposed = false;
    public void Dispose()
    {
        if (!Disposed)
        {
            Disposed = true;
            Console.WriteLine("//////////////////// Disposed");
        }
    }
}

Then I added the scoped service in Program.cs (for ASP.NET 6):

services.AddScoped<DisposableTest>();

Next I added some middleware to write to the console whenever the Response.OnStarting() and Response.OnCompleted() events were run:

app.Use(async delegate (HttpContext Context, Func<Task> Next)
{
    Context.Response.OnStarting(delegate ()
    {
        Console.WriteLine("//////////////////// Response Started");
        return Task.CompletedTask;
    });
    Context.Response.OnCompleted(delegate ()
    {
        Console.WriteLine("//////////////////// Response Completed");
        return Task.CompletedTask;
    });
    await Next();
});

Lastly I added the service to the constructor of HomeController so it gets accessed:

public class HomeController : Controller
{
    public HomeController(DisposableTest TheTest) { }
    public IActionResult Index() { return View(); }
}

After visiting the path /home/index, the IIS Express console showed the following:

enter image description here

It looks like the service is disposed after the response finishes sending.

like image 74
user3163495 Avatar answered Dec 19 '25 15:12

user3163495



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!