0

I am working on asp.net core and I came across concepts like AddTransient, AddSingleton, and AddScoped. They differ in what is the lifecycle of an object.

1.Singleton which creates a single instance throughout the application. It creates the instance for the first time and reuses the same object in all calls.

  1. Scoped lifetime services are created once per request within the scope. It is equivalent to a singleton in the current scope. For example, in MVC it creates one instance for each HTTP request, but it uses the same instance in the other calls within the same web request.
  2. Transient lifetime services are created each time they are requested. This lifetime works best for lightweight, stateless services.

I would like to know what is the meaning of a single HTTP request? If I redirect to another page does that mean it's another HTTP request? P.S I have used the above definitions from AddTransient, AddScoped and AddSingleton Services Differences

Nemanja Todorovic
  • 2,521
  • 2
  • 19
  • 30
Kunal Relan
  • 279
  • 3
  • 8

2 Answers2

1

Scoped is the lifetime which is a bit hard to understand. To start with, why is it called Scoped and not PerRequest etc?

The reason is that the DI container does not have a concept of "requests". But it does have "scopes". When your app starts, it creates the "root" service collection. Now when your app receives an HTTP request, a scope is created from this root service collection. All services that you acquire in controllers etc. are acquired from this scope. If the service is defined as transient or scoped, the scope will create them and dispose them when the scope is disposed, which is when the HTTP request ends. However if it is singleton, the scope gets the single instance from the root service collection.

The difference between transient and scoped here is that if the same service is requested during the same request, the same instance for the scoped service is returned, while transients will always be new instances.

Now for the question you have, when you redirect a user what happens?

  1. Your app receives a request
  2. It returns a 302 Found status code to redirect the caller, this ends the request
  3. The user makes a new request to the URL specified by the Location header in the response to the earlier request

So it is a new request at that point.

juunas
  • 54,244
  • 13
  • 113
  • 149
  • Thank you for your answer. My next question is How many objects are created in the case of transient and scoped when I try to access the code in the Data Access layer and there are more than 1methods (eg. getEmpName, getEmpEmailID etc)? – Kunal Relan Aug 06 '20 at 11:11
  • Different method calls would still call the same instance of the data layer object no? – juunas Aug 06 '20 at 14:18
  • @KunalRelan take a look at [this in the documentation](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.1#lifetime-and-registration-options) the examples show how the lifecycle works specifically for ASP.NET. Also you can play with the code in my answer if the Guid changes it's a new instance. – DalSoft Aug 06 '20 at 14:49
1

Scoped Lifetime means a single HTTP Connection to the server

Once the response is sent and the connection is closed objects registered as Scoped are disposed.

So a redirect is two requests; one for the HTTP 302 redirection and one for the the destination page. You probably only need to worry about this if you are actually injecting a service into whatever is doing the redirection.

This answer discusses alternatives to redirection that will work with Scoped services.

Also take a look at this part of the ASP.NET Documentation. This trivial code shows how Scoped lifetime works.

ScopedService.cs

public class ScopedGuidService
{
   public Guid ScopedGuid => Guid.NewGuid();
}

Startup.cs

public class Startup
{
   public void ConfigureServices(IServiceCollection services)
   {
       services.AddScoped<ScopedGuidService>();
   }
   
   public void Configure(IApplicationBuilder app)
   {
     // Middleware showing how Scoped / per request works
     app.Use((context, next) =>
     {
        var scopedGuidService = 
        context.RequestServices.GetRequiredService<ScopedGuidService>();
        return context.Response.WriteAsync(scopedGuidService.ScopedGuid.ToString());
    });
}

If you run this you will get a different Guid for every request.

DalSoft
  • 10,673
  • 3
  • 42
  • 55