MSDN Documentation

ASP.NET Core Dependency Injection

Dependency Injection (DI) is a fundamental design pattern and an integral part of ASP.NET Core. It's a technique used to achieve Inversion of Control (IoC) and manage dependencies between classes. Instead of a class creating its own dependencies, they are "injected" from an external source.

Core Concepts

What is Dependency Injection?

DI is a design pattern where an object receives other objects that it depends on. These incoming objects are referred to as dependencies. The process of providing the external dependencies is called dependency injection.

Benefits of DI

  • Improved Testability: Makes it easier to mock dependencies for unit testing.
  • Loose Coupling: Reduces the tight coupling between classes, making the codebase more maintainable and flexible.
  • Reusability: Promotes the reuse of components by making them less dependent on specific implementations.
  • Maintainability: Changes in one part of the system have less impact on others.

ASP.NET Core's Built-in DI Container

ASP.NET Core includes a built-in, lightweight DI container that is configured by default. You can use this container to register your services and resolve dependencies.

Service Lifetimes

The DI container manages the lifetime of the objects it creates. There are three primary lifetimes:

  • Singleton: A single instance of the service is created and reused throughout the application's lifetime.
  • Scoped: A single instance of the service is created for each client request.
  • Transient: A new instance of the service is created every time it's requested.

Registering Services

Services are registered with the DI container in the Program.cs file (or Startup.cs in older versions) using the builder.Services collection.

Example Registration (Program.cs)

Here's how you might register a service as a Singleton:

using YourApp.Services;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddSingleton<IMyService, MyService>(); // Registering IMIService as Singleton

var app = builder.Build();

// ... rest of the configuration

Resolving Dependencies

Dependencies are typically resolved through constructor injection. The DI container automatically provides instances of registered services when they are needed by other services or controllers.

Example Constructor Injection

Injecting a service into a controller:

using Microsoft.AspNetCore.Mvc;
using YourApp.Services;

public class HomeController : Controller
{
    private readonly IMyService _myService;

    public HomeController(IMyService myService)
    {
        _myService = myService;
    }

    public IActionResult Index()
    {
        ViewBag.Message = _myService.GetData();
        return View();
    }
}

Common Use Cases

  • Injecting data access repositories.
  • Injecting logging services.
  • Injecting configuration objects.
  • Injecting business logic services.

Tip

Always program to interfaces rather than concrete implementations to maximize the benefits of DI and make your code more flexible.

Advanced DI Topics

  • Factory Registrations: For more complex object creation scenarios.
  • Service Provider: Accessing the service provider directly when needed (use with caution).
  • Third-Party DI Containers: While the built-in container is powerful, you can replace it with containers like Autofac or Unity if required.

Understanding and effectively using Dependency Injection is crucial for building robust, maintainable, and testable ASP.NET Core applications.