Explain dependency injection and its benefits.
15 minintermediateDIdependency-injectiondesign-patternstesting
Quick Answer
Dependency injection is a design pattern where dependencies are provided to a class rather than created internally. Benefits include loose coupling, testability, flexibility, and easier maintenance. Types include constructor, property, and method injection. Enables inversion of control and makes code more modular and testable.
Detailed Answer
Dependency Injection (DI) is a design pattern where objects receive their dependencies from external sources rather than creating them internally. It implements the Dependency Inversion Principle (one of SOLID principles).
Three types of DI:
- Constructor Injection (most common)
- Property/Setter Injection
- Method Injection
Example:
// WITHOUT Dependency Injection (Tight Coupling)
public class EmailService
{
public void SendEmail(string message)
{
Console.WriteLine($"Sending email: {message}");
}
}
public class NotificationService
{
private EmailService emailService;
public NotificationService()
{
// Tightly coupled - hard to test and change
emailService = new EmailService();
}
public void Notify(string message)
{
emailService.SendEmail(message);
}
}
// WITH Dependency Injection (Loose Coupling)
public interface IMessageService
{
void SendMessage(string message);
}
public class EmailService : IMessageService
{
public void SendMessage(string message)
{
Console.WriteLine($"Sending email: {message}");
}
}
public class SmsService : IMessageService
{
public void SendMessage(string message)
{
Console.WriteLine($"Sending SMS: {message}");
}
}
// Constructor Injection
public class NotificationService
{
private readonly IMessageService messageService;
// Dependency is injected through constructor
public NotificationService(IMessageService messageService)
{
this.messageService = messageService;
}
public void Notify(string message)
{
messageService.SendMessage(message);
}
}
// Usage
var emailService = new EmailService();
var notificationService = new NotificationService(emailService);
notificationService.Notify("Hello via Email");
// Can easily switch to SMS
var smsService = new SmsService();
var smsNotificationService = new NotificationService(smsService);
smsNotificationService.Notify("Hello via SMS");
// Using DI Container (e.g., Microsoft.Extensions.DependencyInjection)
// In Startup.cs or Program.cs
services.AddScoped<IMessageService, EmailService>();
services.AddScoped<NotificationService>();
Benefits of Dependency Injection:
- Loose Coupling - Classes depend on abstractions, not concrete implementations
- Testability - Easy to mock dependencies for unit testing
- Maintainability - Changes in dependencies don't affect dependent classes
- Flexibility - Easy to swap implementations without changing code
- Reusability - Components can be reused in different contexts