Blazor Dependency Injection
Dependency Injection (DI) is a core design pattern used extensively in Blazor. It allows components and services to declare their dependencies, and the Blazor framework provides mechanisms to satisfy those dependencies. This promotes loosely coupled code, making applications easier to test, maintain, and scale.
Understanding Dependency Injection
In Blazor, DI is managed by a service container. You register your services with the container, and when a component or another service needs an instance of that service, the container provides it. This is typically done through constructor injection, where dependencies are requested as parameters in a constructor.
Registering Services
Services are registered in the Program.cs
file (or Startup.cs
for older ASP.NET Core versions) within the service collection. The most common registration methods are:
AddTransient<TService, TImplementation>()
: A new instance of the service is created every time it's requested.AddScoped<TService, TImplementation>()
: A single instance of the service is created per client request (e.g., per browser tab session in Blazor WebAssembly).AddSingleton<TService, TImplementation>()
: A single instance of the service is created and reused throughout the application's lifetime.
For example, to register a custom service called MyDataService
:
// Program.cs
using Microsoft.Extensions.DependencyInjection;
using System;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor(); // Or builder.Services.AddBlazorWebAssembly()
// Register a transient service
builder.Services.AddTransient<MyDataService>();
// Register a scoped service
builder.Services.AddScoped<IScopedService, ScopedServiceImplementation>();
// Register a singleton service
builder.Services.AddSingleton<ILoggerService, ConsoleLoggerService>();
var app = builder.Build();
// ... configuration ...
app.Run();
public interface IScopedService { }
public class ScopedServiceImplementation : IScopedService { }
public interface ILoggerService { }
public class ConsoleLoggerService : ILoggerService { }
public class MyDataService { }
Injecting Services into Components
You can inject registered services into your Blazor components using the [Inject]
attribute. This attribute tells Blazor to resolve and inject an instance of the specified service into the property.
// MyComponent.razor
@page "/mycomponent"
@inject MyDataService DataService
@inject IScopedService ScopedService
@inject ILoggerService Logger
My Component
Data from service: @DataService.GetData()
Scoped service instance ID: @ScopedService.GetHashCode()
@code {
protected override void OnInitialized()
{
Logger.Log("MyComponent initialized.");
}
}
Tip
If a service is registered as AddScoped
, ensure that its lifetime is compatible with the component it's injected into. For Blazor WebAssembly, a scoped service lives for the duration of the browser session.
Service Lifetimes Explained
Lifetime | Description | When to Use |
---|---|---|
Transient | A new instance is created each time it's requested. | Lightweight services or services that should not maintain state between requests. |
Scoped | A single instance is created per client connection or session. | Services that need to maintain state within a specific user's interaction, like a shopping cart or user session data. |
Singleton | A single instance is created for the entire application lifetime. | Global configuration, logging services, or services that are expensive to create and can be safely shared. |
Common Scenarios
- Data Access Services: Injecting services responsible for fetching data from an API or database.
- State Management Services: Creating services to manage application-wide state.
- Utility Services: Injecting helper classes for common tasks like logging, authentication, or notification.
By leveraging Blazor's built-in DI container, you can build more robust, testable, and maintainable applications. Familiarize yourself with the different service lifetimes to choose the most appropriate one for each of your services.