Dependency Injection in .NET

Dependency Injection (DI) is a fundamental design pattern used in modern software development, especially in object-oriented programming. It's a technique where a class receives its dependencies from an external source rather than creating them itself. This promotes loose coupling, making code more modular, testable, and maintainable.

In .NET, DI is deeply integrated into the framework, particularly with ASP.NET Core. This section will guide you through the core concepts of DI in .NET.

Core Concepts of Dependency Injection

At its heart, DI involves three main components:

The injector is typically an implementation of a DI container, also known as an inversion of control (IoC) container.

The .NET DI Container

.NET provides a built-in, lightweight DI container that can be used to manage the lifecycle and injection of services.

Service Lifetimes

The DI container manages the lifetime of registered services. The most common lifetimes are:

Registering Services

You register services with the DI container, typically in the application's startup code (e.g., in the Startup.cs file for ASP.NET Core applications).

Example of registering services:


using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();

// Register a singleton service
services.AddSingleton<IMySingletonService, MySingletonService>();

// Register a scoped service
services.AddScoped<IMyScopedService, MyScopedService>();

// Register a transient service
services.AddTransient<IMyTransientService, MyTransientService>();

var serviceProvider = services.BuildServiceProvider();
            

Injecting Services

Services can be injected into constructors, properties, or methods. Constructor injection is the most common and recommended approach.

Example of constructor injection:


public class MyController
{
    private readonly IMyScopedService _scopedService;
    private readonly IMyTransientService _transientService;

    public MyController(IMyScopedService scopedService, IMyTransientService transientService)
    {
        _scopedService = scopedService;
        _transientService = transientService;
    }

    // ... controller actions
}
            

Benefits of Dependency Injection

Important Note:

While .NET provides a built-in DI container, you can also use third-party containers like Autofac, Ninject, or StructureMap, which offer more advanced features.

Common DI Scenarios

Web Applications (ASP.NET Core)

In ASP.NET Core, DI is built into the framework. Services are typically registered in the ConfigureServices method of the Startup class and automatically injected into controllers, Razor Pages, middleware, and other components.

Background Services

DI is crucial for managing dependencies within background services (e.g., using IHostedService) where you need access to scoped or singleton services.

Further Reading