
July 15, 2025 10:08 by
Peter
Dependency Injection (DI): What is it?
A design pattern called Dependency Injection (DI) is used to accomplish loose coupling between classes and their dependencies. Dependencies are injected from the outside, typically by a framework like.NET Core, rather than being created by a class itself. This encourages improved modularity, testability, and maintainability in application design.

Why Use DI?
Improves testability (easily mock dependencies)
Enhances flexibility and maintainability
Supports SOLID principles, especially:
- Inversion of Control (IoC)
- Single Responsibility Principle
How DI Works in .NET Core?
.NET Core comes with a built-in IoC container that supports three main service lifetimes:
Lifetime | Description | Example Use Case |
Singleton |
One instance for the entire application |
Caching, config, loggers |
Scoped |
One instance per HTTP request |
User/session-level services |
Transient |
New instance every time it's requested |
Lightweight, stateless logic |
Step-by-Step Example: Injecting a Service
1. Define an Interface
public interface IMessageService
{
string GetMessage();
}
2. Create a Concrete Implementation
public class HelloMessageService : IMessageService
{
public string GetMessage()
{
return "Hello from DI!";
}
}
3. Register the Service in the Program.cs (.NET 6+)
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IMessageService, HelloMessageService>(); // DI registration
4. Inject the Service in a Controller
[ApiController]
[Route("[controller]")]
public class HomeController : ControllerBase
{
private readonly IMessageService _messageService;
public HomeController(IMessageService messageService)
{
_messageService = messageService;
}
[HttpGet]
public string Get() => _messageService.GetMessage();
}
Output
GET /home
=> "Hello from DI!"
Real-World Use Case
In a recent project, we used DI to inject:
- ILoggingService
- IEmailService
- IUserRepository
This allowed us to easily swap implementations during unit testing and to mock external services such as SendGrid and SQL Server, enabling a much more testable and scalable architecture.
Summary
- DI is built into .NET Core via IServiceCollection.
- Encourages clean, testable, and modular code.
- Supports different service lifetimes (Singleton, Scoped, Transient).
- Use constructor injection as the standard approach.