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:

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

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.