LARAVEL

Laravel Service Container & DI

February 8, 2024 15 min read

Introduction

The service container is a powerful tool for managing class dependencies and performing dependency injection. Understanding the container is essential for building maintainable Laravel applications.

Service Binding

Register services in service providers:

// app/Providers/AppServiceProvider.php

public function register()
{
    // Bind interface to implementation
    $this->app->bind(
        PaymentGatewayInterface::class,
        StripePaymentGateway::class
    );
    
    // Singleton binding
    $this->app->singleton(
        CacheService::class,
        function ($app) {
            return new CacheService($app->make(Config::class));
        }
    );
    
    // Instance binding
    $this->app->instance(Logger::class, $logger);
}

Resolving Services

Laravel can automatically resolve dependencies:

// Automatic resolution via constructor injection
class OrderController extends Controller
{
    public function __construct(
        private OrderService $orderService,
        private PaymentGatewayInterface $payment
    ) {}
    
    public function store(Request $request)
    {
        // Laravel automatically injects dependencies
        return $this->orderService->process($request->all());
    }
}

// Manual resolution
$service = app(PaymentGatewayInterface::class);

// With parameters
$service = app(AnalyticsService::class, ['driver' => 'google']);

Contextual Binding

Bind different implementations based on context:

// Different implementations for different contexts
$this->app->when(InvoiceController::class)
    ->needs(PaymentGatewayInterface::class)
    ->give(StripePaymentGateway::class);

$this->app->when(SubscriptionController::class)
    ->needs(PaymentGatewayInterface::class)
    ->give(PayPalPaymentGateway::class);

Tagging Services

Group services using tags:

// Register services with tags
$this->app->tag(ReportGenerator::class, 'reports');
$this->app->tag(PdfReportGenerator::class, 'reports');
$this->app->tag(ExcelReportGenerator::class, 'reports');

// Resolve all tagged services
$reports = $this->app->tagged('reports');

foreach ($reports as $report) {
    $report->generate();
}

Summary

The Laravel service container is the foundation of dependency injection in Laravel. Master binding, resolution, and contextual binding to build flexible applications.

For more Laravel tutorials, see Facades and Helpers and Repository Pattern.