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."