architecture
Junior
What is dependency injection?
Short Answer
Dependency injection is a design pattern where a class receives its dependencies from outside rather than creating them internally.
Detailed Answer
Dependency Injection (DI) means a class doesn\'t create its own dependencies — they\'re injected (usually via constructor):
Without DI (tight coupling):
class OrderService {
private $mailer; // Creates its own dependency
public function __construct() {
$this->mailer = new Mailer();
}
}
With DI (loose coupling):
class OrderService {
public function __construct(private Mailer $mailer) {} // Injected
}
Benefits:
- Loose coupling: swap implementations easily
- Testability: inject mocks/stubs in tests
- Single Responsibility: class doesn\'t manage dependencies
- Flexibility: change implementations without changing the class
Laravel\'s container automates DI: it reads type hints and injects the correct implementation.
Code Example
Example
<?php
// Without DI - hard to test, tightly coupled
class ReportService
{
public function generate()
{
$pdf = new PdfGenerator(); // Can't swap this
$mailer = new Mailer(); // Can't mock this
// ...
}
}
// With DI - testable, flexible
class ReportService
{
public function __construct(
private PdfGeneratorInterface $pdf,
private MailerInterface $mailer
) {}
public function generate(): Report
{
$report = $this->pdf->create($data);
$this->mailer->send($report);
return $report;
}
}
// Testing with DI
class ReportServiceTest extends TestCase
{
public function test_generate(): void
{
$pdf = Mockery::mock(PdfGeneratorInterface::class);
$mailer = Mockery::mock(MailerInterface::class);
$service = new ReportService($pdf, $mailer);
// Test with mocks
}
}
Interview Tip
Give a concrete test example: "With DI, I can inject a mock Mailer that doesn't actually send emails during tests."