liveBook · Manning

Service lifetime

As explained in ASP.NET Core in Action, 3e

A service lifetime is the dependency-injection rule that determines how long a registered service instance is retained and when it is disposed.

A service lifetime tells the dependency-injection (DI) container when to reuse a registered service instance and when to create a new one. Choose the lifetime when registering the service, alongside its service type and implementation type. section 9.4 section 9.1

ASP.NET Core’s built-in container offers three lifetimes:

  • Transient: create a new instance every time the service is requested, even if it is requested twice within one dependency graph. section 9.4
  • Scoped: reuse one instance within a scope and create a different instance for another scope. Each ASP.NET Core web request has its own scope. section 9.4
  • Singleton: reuse the same instance throughout the application, regardless of scope. section 9.4

Registering an email service

Registering IEmailSender with AddScoped<IEmailSender, EmailSender>() gives requests within one scope the same EmailSender instance. Registering MessageFactory with AddSingleton<MessageFactory>() instead makes its instance available for reuse across scopes. If you already have an object, passing it to AddSingleton registers that particular object; a scoped factory lambda can create an object when a new scoped instance is needed. section 9.1 section 9.2

Figure 9.6 The DI container uses two instances of DataContext for each request. Depending on the lifetime with which the DataContext type is registered, the container might create one, two, or four instances of DataContext.
CH09_F06_Lock3

Compare the DataContext instances used across requests. Changing its lifetime changes whether the handler and its Repository dependency receive matching or different instances. section 9.4

Lifetime choices matter beyond ordinary request handling. A long-lived service that captures a shorter-lived dependency can cause hard-to-debug problems. When resolving a scoped service manually outside a request, create a scope, resolve the service from that scope’s ServiceProvider, and dispose of the scope afterward. CreateAsyncScope() is generally preferred where available. section 9.4 section 9.5

How ASP.NET Core in Action, 3e covers it

How deep it goes
Defines all three lifetimes, illustrates their effect on instance reuse, and addresses manual scoped resolution and disposal.
Examples
Uses email-service registrations and a DataContext shared with a Repository to contrast instance reuse.
What it assumes
Assumes basic dependency-injection concepts while defining lifetime and showing how service registrations specify it.
What you can do after
Operate/configure it by choosing transient, scoped, or singleton registration and creating a scope for manual scoped resolution.
How it connects
Connects dependency injection, service registration, dependency graphs, request scopes, factory functions, and service disposal.

Also explained in

Compare how 2 books explain service lifetime →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of ASP.NET Core in Action, 3e. The section links point to the parts of the book it draws on.