Skip to main content

service container in laravel with example

he Laravel service container, also known as the Inversion of Control (IoC) container, is a powerful tool for managing class dependencies and performing dependency injection. It acts as a central registry for your application's classes, allowing Laravel to automatically resolve and inject required dependencies when needed. 
Key Concepts:
  • Binding: 
    Registering a class or an interface and its implementation with the container. This tells the container how to build an instance of that class or what implementation to use for a given interface.
  • Resolving: 
    Retrieving an instance of a registered class or implementation from the container. The container handles the creation of the object and its dependencies.
  • Dependency Injection: 
    The process of providing a class with its dependencies through its constructor or setter methods, rather than the class creating them itself. The service container automates this.
Example:
Consider a scenario where you have a NotificationService responsible for sending notifications and a UserService that utilizes this service.
Code
// app/Services/NotificationService.php
namespace App\Services;

class NotificationService
{
    public function send(string $message): string
    {
        return "Sending Notification: " . $message;
    }
}

// app/Services/UserService.php
namespace App\Services;

class UserService
{
    protected NotificationService $notificationService;

    // The NotificationService is injected via the constructor
    public function __construct(NotificationService $notificationService)
    {
        $this->notificationService = $notificationService;
    }

    public function notifyUser(string $message): string
    {
        return $this->notificationService->send($message);
    }
}
Using the Service Container:
  • Automatic Resolution in Controllers/Jobs: Laravel automatically resolves dependencies for constructors in controllers, jobs, and other framework-managed classes.
Code
    // app/Http/Controllers/UserController.php
    namespace App\Http\Controllers;

    use App\Services\UserService;
    use Illuminate\Http\Request;

    class UserController extends Controller
    {
        public function __construct(protected UserService $userService)
        {
            // The UserService instance is automatically injected here
        }

        public function showNotifications()
        {
            $message = $this->userService->notifyUser('Welcome to our application!');
            return view('notifications', compact('message'));
        }
    }
  • Manual Resolution: You can also explicitly resolve instances from the container using the app() helper or App::make().
Code
    use App\Services\UserService;

    // ...

    $userService = app()->make(UserService::class);
    $message = $userService->notifyUser('Manual notification!');
Binding Interfaces to Implementations (Advanced):
This is particularly useful for testability and flexibility.
Code
// app/Contracts/MailerInterface.php
namespace App\Contracts;

interface MailerInterface
{
    public function sendMail(string $to, string $subject, string $body): string;
}

// app/Services/SmtpMailer.php
namespace App\Services;

use App\Contracts\MailerInterface;

class SmtpMailer implements MailerInterface
{
    public function sendMail(string $to, string $subject, string $body): string
    {
        return "Sending SMTP mail to {$to}: {$subject} - {$body}";
    }
}

// app/Providers/AppServiceProvider.php (or a custom Service Provider)
namespace App\Providers;

use App\Contracts\MailerInterface;
use App\Services\SmtpMailer;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->bind(MailerInterface::class, SmtpMailer::class);
    }
}
Now, anywhere you type-hint MailerInterface, the container will inject an instance of SmtpMailer.
Code
// In a controller or job
use App\Contracts\MailerInterface;

class OrderController extends Controller
{
    public function __construct(protected MailerInterface $mailer)
    {
        // $this->mailer is an instance of SmtpMailer
    }

    public function processOrder()
    {
        $this->mailer->sendMail('user@example.com', 'Order Confirmation', 'Your order has been placed.');
    }
}