Dependency Injection (DI) is one of the most commonly asked .NET Core interview questions.
What is Dependency Injection in .NET Core?
Dependency Injection (DI) is a design pattern where an object receives its dependencies from outside instead of creating them itself.
Without Dependency Injection (Bad Practice)
public class OrderService
{
private EmailService _emailService;
public OrderService()
{
_emailService = new EmailService(); // tightly coupled
}
public void PlaceOrder()
{
_emailService.SendEmail();
}
}
Problems here
-
Tight coupling
-
Hard to test
-
Hard to change implementation
-
Violates SOLID principles
With Dependency Injection (Good Practice)
public class OrderService
{
private readonly IEmailService _emailService;
public OrderService(IEmailService emailService)
{
_emailService = emailService;
}
public void PlaceOrder()
{
_emailService.SendEmail();
}
}
Now dependency is injected from outside.
Step-by-Step Simplest Example
Step 1: Create Interface
public interface IMessageService
{
void SendMessage();
}
Step 2: Create Implementation
public class EmailService : IMessageService
{
public void SendMessage()
{
Console.WriteLine("Email Sent");
}
}
Step 3: Register in Program.cs
(.NET 6 / .NET 7 / .NET 8)
builder.Services.AddScoped<IMessageService, EmailService>();
Step 4: Inject in Controller
public class HomeController : Controller
{
private readonly IMessageService _messageService;
public HomeController(IMessageService messageService)
{
_messageService = messageService;
}
public IActionResult Index()
{
_messageService.SendMessage();
return View();
}
}
That's it.
.NET Core automatically injects the dependency.
Types of Dependency Injection Lifetimes
This is very important for interviews 👇
1. Transient
New instance every time
builder.Services.AddTransient<IMessageService, EmailService>();
Use when:
-
Lightweight services
-
No shared state
2. Scoped
One instance per request (Most commonly used)
builder.Services.AddScoped<IMessageService, EmailService>();
Use when:
-
Database services
-
Business logic services
Example:
-
DbContext (Scoped)
3. Singleton
Single instance for entire application
builder.Services.AddSingleton<IMessageService, EmailService>();
Use when:
-
Caching
-
Configuration
-
Logging
Real World Example
public interface IUserRepository
{
List<string> GetUsers();
}
public class UserRepository : IUserRepository
{
public List<string> GetUsers()
{
return new List<string> { "John", "David" };
}
}
Register:
builder.Services.AddScoped<IUserRepository, UserRepository>();
Inject:
public class UserService
{
private readonly IUserRepository _repository;
public UserService(IUserRepository repository)
{
_repository = repository;
}
public void GetUsers()
{
var users = _repository.GetUsers();
}
}
Why Dependency Injection is Important
Interview-friendly points:
-
Loose coupling
-
Easy unit testing
-
Maintainable code
-
Better scalability
-
Follow SOLID principles
-
Easy to replace implementations
One Line Interview Answer
Dependency Injection is a design pattern where dependencies are provided to a class from outside instead of creating them inside the class, helping achieve loose coupling and better maintainability.
Constructor Injection vs Method Injection vs Property Injection
Most commonly used: Constructor Injection
Constructor Injection (Recommended)
public HomeController(IMessageService messageService)
Property Injection
public IMessageService MessageService { get; set; }
Method Injection
public void Send(IMessageService messageService)
Most Asked Interview Question
Q: Does .NET Core support DI by default?
Yes. .NET Core has built-in Dependency Injection container.
Short Real-Life Example
Think of Dependency Injection like:
You don't cook food yourself.
You order from restaurant.
Restaurant = Dependency
Your class doesn't create dependencies — they are injected.
