Dependency Injection in ASP.NET Core MVC

Dependency Injection (DI) is a powerful technique for building loosely coupled applications. ASP.NET Core has built-in support for DI, making it easy to manage the dependencies of your application components.

What is Dependency Injection?

Dependency Injection is a design pattern where a class receives its dependencies (other objects it needs to function) from an external source rather than creating them itself. This external source is often referred to as an "injector" or "container."

Consider a service that needs to log messages. Instead of the service creating its own logger instance, the logger instance is "injected" into the service. This makes the service easier to test and reuse, as you can swap out different logger implementations without modifying the service itself.

The Built-in DI Container

ASP.NET Core includes a lightweight, built-in DI container. This container manages the creation and lifetime of services and injects them into other classes. You configure the DI container in the Startup.cs file (or Program.cs in .NET 6+ minimal APIs).

Registering Services

You register your services with the DI container using the Add... methods on the IServiceCollection object. Common registration methods include:

For example, to register a custom logging service:


// In Startup.cs (ConfigureServices method) or Program.cs
public void ConfigureServices(IServiceCollection services)
{
    // ... other service registrations ...

    // Register MyCustomLogger as a singleton
    services.AddSingleton<ILoggerService, MyCustomLogger>();
}
        

Consuming Services

You can consume injected services in a few ways:

Constructor Injection

This is the most common and recommended way. Dependencies are requested via the class constructor.


public class HomeController : Controller
{
    private readonly ILoggerService _logger;

    // The ILoggerService is injected via the constructor
    public HomeController(ILoggerService logger)
    {
        _logger = logger;
    }

    public IActionResult Index()
    {
        _logger.LogMessage("Accessed the Index page.");
        return View();
    }
}
        

Property Injection (Less common in ASP.NET Core)

Dependencies are provided through public properties.


public class MyService
{
    // The DI container can inject values into public properties
    [FromServices]
    public IAnotherService AnotherService { get; set; }

    public void DoSomething()
    {
        AnotherService.PerformAction();
    }
}
        

Method Call Injection (Rare in ASP.NET Core)

Dependencies are passed as parameters to methods.

Built-in Services

ASP.NET Core itself relies heavily on DI and provides many services that you can inject into your application. Some common examples include:

Note on .NET 6+ Minimal APIs

In .NET 6 and later versions using minimal APIs, the DI configuration is typically done directly in the Program.cs file, often using the builder.Services collection.

Benefits of Dependency Injection

Tip

Always favor constructor injection when possible, as it makes dependencies explicit and ensures that objects are created in a valid state.

By understanding and leveraging dependency injection, you can build more robust, maintainable, and testable ASP.NET Core applications.