Dependency Injection (DI) is a technique for achieving Inversion of Control (IoC) between classes and their dependencies. In other words, it is a technique for accessing services configured in a central location.
Blazor's DI system is based on the DI system in ASP.NET Core. DI services can be configured with the following lifetimes:
Method | Description |
---|---|
Singleton | DI creates a single instance of the service. All components requiring this service receive a reference to this instance. |
Transient | Whenever a component requires this service, it receives a new instance of the service. |
Scoped | Blazor doesn't currently have the concept of DI scopes. Scoped behaves like Singleton. Therefore, prefer Singleton and avoid Scoped. |
By default, Blazor's BrowserServiceProvider
automatically adds the following services to the service collection of an application.
Method | Description |
---|---|
IUriHelper | Helpers for working with URIs and navigation state (singleton). |
HttpClient | Provides methods for sending HTTP requests and receiving HTTP responses from a resource identified by a URI (singleton). |
Here is a simple service which will retrieve employee's data asynchronously.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace BlazorApplication.Services
{
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public interface IRepository
{
Task<IReadOnlyList<Employee>> GetAllEmployeesAsync();
}
public class Repository : IRepository
{
private static Employee[] Employees { get; set; } = new[]
{
new Employee { FirstName = "Andy", LastName = "White" },
new Employee { FirstName = "Mark", LastName = "Doe" }
};
public async Task<IReadOnlyList<Employee>> GetAllEmployeesAsync()
{
await Task.Delay(100);
return Repository.Employees;
}
}
}
When a new Blazor application is created, you will see Startup.cs
file which contains ConfigureServices
and Configure
methods.
using Microsoft.AspNetCore.Blazor.Builder;
using Microsoft.Extensions.DependencyInjection;
namespace BlazorApplication
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(IBlazorApplicationBuilder app)
{
app.AddComponent<App>("app");
}
}
}
The ConfigureServices method has IServiceCollection as an argument, which is a list of service descriptor objects (ServiceDescriptor). You can add services to the service collection by providing service descriptors.
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IRepository, Repository>();
}
To inject a service in a component, use the @inject
keyword as shown in the following sample.
@using BlazorApplication.Services
@page "/"
@inject IRepository Repository
<h1>Hello, world!</h1>
<ul>
@if (Employees != null)
{
@foreach (var emp in Employees)
{
<li>@emp.FirstName @emp.LastName</li>
}
}
</ul>
@functions {
private IReadOnlyList<Employee> Employees;
protected override async Task OnInitAsync()
{
Employees = await Repository.GetAllEmployeesAsync();
}
}
Technically, it generates a property and decorate it with the InjectAttribute
attribute.
If a base class is required for Blazor components and injected properties are also required for the base class, then add InjectAttribute
manually.
public class ComponentBase : BlazorComponent
{
[Inject]
protected IRepository Repository { get; set; }
...
}