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; }
    ...
}