liveBook · Manning

Service registration

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

Service registration is the configuration that maps a requested service or interface to the implementation the dependency-injection container should provide.

Service registration tells a dependency-injection (DI) container what to provide when code requests a service. A typical registration means, “When IEmailSender is requested, use EmailSender.” The endpoint can then depend on the interface rather than construct EmailSender itself, making the implementation easier to replace for testing or other needs. section 8.2 section 9.1

In ASP.NET Core, add registrations to builder.Services in Program.cs, before builder.Build(). This property is an IServiceCollection. Many core services are registered automatically; optional framework features and your own services may need explicit registration. section 8.4 section 9.1

Choose a registration that matches what needs to be supplied:

  • For an optional framework feature, use its extension method—for example, builder.Services.AddRazorPages() adds the services Razor Pages needs. MapRazorPages() separately maps its endpoints. section 8.4
  • For an application service, register its interface and implementation, plus the dependencies needed to construct that implementation. The email-sending example registers IEmailSender as EmailSender, along with NetworkClient and MessageFactory; EmailServerSettings also needs registration. section 9.1
  • Choose a lifetime as part of registration: transient creates an instance each time, scoped reuses one within a scope (one per web request), and singleton reuses one across scopes. section 9.4
Listing 9.3 Registering services with the DI container
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
 
builder.Services.AddScoped<IEmailSender, EmailSender>();   #1
builder.Services.AddScoped<NetworkClient>();               #2
builder.Services.AddSingleton<MessageFactory>();           #3
 
WebApplication app = builder.Build();
 
app.MapGet("/register/{username}", RegisterUser);
 
app.Run();
 
string RegisterUser(string username, IEmailSender emailSender)
{
    emailSender.SendEmail(username);
    return $"Email sent to {username}!";
}
#1 Whenever you require an IEmailSender, use EmailSender.
#2 Whenever you require a NetworkClient, use NetworkClient.
#3 Whenever you require a MessageFactory, use MessageFactory.

The complete registration example shows builder.Services calls before the application is built and an endpoint handler that requests IEmailSender without constructing it. section 9.1

A registered service can be supplied through an endpoint-handler parameter. If a required service is missing, the application can fail at runtime; for an unregistered minimal-API parameter, the framework may instead try to bind it from the request body. Check that the requested service and its dependencies are registered. section 7.6.2 section 9.1

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

How deep it goes
Works through custom and framework registrations, dependency graphs, missing-service failures, and lifetime choices; leaves third-party container integration to advanced configuration.
Examples
Uses an email-sending endpoint with IEmailSender dependencies, AddRazorPages() setup, and DataContext instances to illustrate registration and lifetimes.
What it assumes
Builds on basic dependency injection and C# endpoint handlers while introducing how to register application services.
What you can do after
Operate/configure ASP.NET Core’s built-in DI container to register framework and application services, choose lifetimes, and investigate missing registrations.
How it connects
Connects dependency injection, interfaces, endpoint-handler injection, dependency graphs, Razor Pages, and service lifetimes.

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.