Dependency Injection in ASP.NET Core

Dependency Injection (DI) is a fundamental design pattern used extensively in ASP.NET Core. It's a technique where a class receives its dependencies (other objects it needs to function) from an external source rather than creating them itself. This promotes loose coupling, testability, and maintainability of your applications.

Core Concepts

The DI system in ASP.NET Core has three key parts:

Registering and Resolving Services

You register services with the DI container in the Program.cs (or Startup.cs in older versions) file using the ConfigureServices method. ASP.NET Core provides several ways to register services, depending on their lifetime:

// Program.cs (ASP.NET Core 6+) using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); // Registering a service as a Singleton builder.Services.AddSingleton(); // Registering a service as Scoped builder.Services.AddScoped(); // Registering a service as Transient builder.Services.AddTransient(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();

Injecting Dependencies

Dependencies are typically injected into consuming classes through their constructors. ASP.NET Core's DI container automatically resolves and injects these dependencies when it creates an instance of the consuming class.

// Example Controller using Microsoft.AspNetCore.Mvc; public class HomeController : Controller { private readonly IMySingletonService _singletonService; private readonly IMyScopedService _scopedService; private readonly IMyTransientService _transientService; public HomeController( IMySingletonService singletonService, IMyScopedService scopedService, IMyTransientService transientService) { _singletonService = singletonService; _scopedService = scopedService; _transientService = transientService; } public IActionResult Index() { ViewBag.SingletonMessage = _singletonService.Operation(); ViewBag.ScopedMessage = _scopedService.Operation(); ViewBag.TransientMessage = _transientService.Operation(); return View(); } }

Benefits of Dependency Injection

Tip: Always program to interfaces, not concrete implementations, when defining dependencies. This further enhances flexibility and testability.

Note: While ASP.NET Core has a built-in DI container, you can also integrate third-party containers like Autofac, Ninject, or StructureMap if you require more advanced features.

Resolving Dependencies in Razor Views/Pages

You can also inject services directly into Razor views and pages using the @inject directive.

@inject MyApp.Services.IMyScopedService ScopedService @inject MyApp.Services.IMySingletonService SingletonService @{ ViewData["Title"] = "Home Page"; }

Welcome

Singleton operation: @SingletonService.Operation()

Scoped operation: @ScopedService.Operation()

This makes it convenient to access common services directly within your presentation layer.