Dependency Injection (DI) is a fundamental concept in ASP.NET Core. It allows you to write loosely coupled, testable, and maintainable code by injecting the required dependencies into your classes instead of hard-coding them. ASP.NET Core has a built-in DI container that supports constructor injection and handles object lifetimes efficiently.
What is Dependency Injection?
Dependency Injection (DI) is a design pattern used to achieve Inversion of Control (IoC) between classes and their dependencies. Rather than a class creating its own dependencies, they are provided from outside, typically via the constructor.
📌 In simple terms: A class doesn’t create what it needs — it receives it from someone else.
Use of Dependency Injection:
- Promotes loose coupling
- Makes code testable
- Supports the separation of concerns
- Encourages interface-based programming
Step-by-Step Implementation of Dependency Injection:
Step 1: Create a New ASP.NET Core Project: You can create a new project using the .NET CLI or Visual Studio.
dotnet new webapi -n MyApi cd MyApi
Step 2: Define a Service Interface: Create an interface that defines the contract for the service.
public interface IProductService { IEnumerable<string> GetProducts(); }
public class ProductService : IProductService { public IEnumerable<string> GetProducts() { return new List<string> { "Product1", "Product2", "Product3" }; } }
Step 4: Registering Services in the Dependency Injection Container.
var builder = WebApplication.CreateBuilder(args); // Register the ProductService with the DI container builder.Services.AddScoped<IProductService, ProductService>(); var app = builder.Build();
Step 5: Injecting Dependencies into Controllers
using Microsoft.AspNetCore.Mvc; [ApiController] [Route("api/[controller]")] public class ProductsController : ControllerBase { private readonly IProductService _productService; // Constructor injection public ProductsController(IProductService productService) { _productService = productService; } [HttpGet] public IActionResult Get() { var products = _productService.GetProducts(); return Ok(products); } }
Step 6: Run the Solution.
Service Lifetimes in ASP.NET Core.
In ASP.NET Core, when you register a service in the Dependency Injection (DI) container, you must specify its lifetime. This tells the framework how long to keep the object in memory and how often to create a new one.
ASP.NET Core provides three service lifetimes:
- Singleton
- Scoped
- Transient
Singleton: A single instance is created once and shared throughout the application's entire lifetime.
Use When:
- The service is stateless and thread-safe
- You want to cache or reuse resources
- Examples: Logging, Configuration, In-memory cache
Scoped: A new instance is created per HTTP request. The same instance is reused within that request.
Use When:
- You want to maintain state only during a single request
- You’re working with Entity Framework Core DbContext
Transient: A new instance is created every time the service is requested (even multiple times within the same request).
Use When:
- Service is lightweight and stateless
- You need fresh data or processing logic every time
Example:
builder.Services.AddSingleton<ISingletonService, MyService>(); builder.Services.AddScoped<IScopedService, MyService>(); builder.Services.AddTransient<ITransientService, MyService>();
Example: Unit Testing with DI.
var mockService = new Mock<IProductService>(); mockService.Setup(x => x.GetAll()).Returns(new[] { "Test Product" }); var controller = new ProductsController(mockService.Object); var result = controller.GetAll();
Thanks to DI and interface-based design, testing is simple and clean.
Dependency Injection in ASP.NET Core is not just a feature — it’s a core part of the framework. By registering services properly, choosing the right lifetimes, and following interface-based design, you can build robust, maintainable, and testable web applications with ease.
No comments
Post a Comment