Back to L Topics
Lbeginner Level 30 min read Afzaal Suleman

Laravel Service Container

Laravel’s Service Container manages and creates class dependencies automatically. It enables Dependency Injection, so Laravel provides the services a class needs instead of you manually creating them.

L Study Chapter · Official Reference

Let's explain Service Container from zero, with a very simple Laravel example.

1. First understand a normal PHP class

We have:

class PaymentService
{
    public function pay()
    {
        return "Payment successful";
    }
}

To use this class normally, we do:

$payment = new PaymentService();

$payment->pay();

Here you are creating the object:

new PaymentService()

2. Now Laravel does it for you

Suppose you have:

class OrderController
{
    public function __construct(
        private PaymentService $payment
    ) {}
}

You didn't write:

$this->payment = new PaymentService();

So how does $payment get created?

Laravel creates it for you.

That's where the Service Container comes in.

OrderController
      |
      | needs PaymentService
      ↓
┌──────────────────────┐
│ Laravel Service      │
│ Container             │
│                      │
│ creates the object   │
└──────────────────────┘
      |
      ↓
PaymentService object
      |
      ↓
OrderController

So when Laravel sees:

PaymentService $payment

it basically thinks:

"This controller needs a PaymentService. Let me create one and give it to the controller."


3. This is called Dependency Injection

Your controller depends on PaymentService.

class OrderController
{
    public function __construct(
        private PaymentService $payment
    ) {}
}

Here:

OrderController
      ↓
depends on
      ↓
PaymentService

Laravel injects that dependency.

That's called:

Dependency Injection (DI).

And the thing responsible for resolving that dependency is:

Service Container.


4. Why is this useful?

Now imagine PaymentService needs another service:

class PaymentService
{
    public function __construct(
        private StripeService $stripe
    ) {}
}

And StripeService needs:

class StripeService
{
    public function __construct(
        private ApiClient $client
    ) {}
}

Now you have:

OrderController
       ↓
PaymentService
       ↓
StripeService
       ↓
ApiClient

You don't need to manually do:

$client = new ApiClient();

$stripe = new StripeService($client);

$payment = new PaymentService($stripe);

$controller = new OrderController($payment);

😵 That's a lot of work.

Laravel's container can resolve this dependency chain for you.

             Laravel
          Service Container
                ↓
        creates ApiClient
                ↓
        creates StripeService
                ↓
        creates PaymentService
                ↓
        gives it to Controller

That's the main purpose of the Service Container.


5. Now understand Facade

You asked about Facades before.

Consider:

Log::info('Order created');

Log is a Laravel Facade.

You don't have to manually create the logger.

Conceptually:

Log::info()
    ↓
Facade
    ↓
Service Container
    ↓
Logger Service
    ↓
info()

Another example:

Cache::get('users');

Conceptually:

Cache::get()
    ↓
Cache Facade
    ↓
Service Container
    ↓
Cache Service

6. Remember these three things

This is the most important part for your interview:

Service Container

Manages and creates objects/dependencies.

Container → creates PaymentService

Dependency Injection

A class receives the dependency it needs.

public function __construct(PaymentService $payment)

Facade

Provides a convenient, static-looking way to access Laravel services.

Cache::get();
Log::info();
DB::table();

One final example

class OrderController
{
    public function __construct(
        private PaymentService $payment
    ) {}

    public function store()
    {
        $this->payment->pay();
    }
}

What's happening?

1. Laravel wants to create OrderController
                    ↓
2. Laravel sees:
   "OrderController needs PaymentService"
                    ↓
3. Service Container creates PaymentService
                    ↓
4. Laravel injects PaymentService
   into OrderController
                    ↓
5. Controller can use:
   $this->payment->pay()

So when you see this in Laravel:

public function __construct(SomeService $service)

think:

"Laravel's Service Container will give this class the service it needs."

That's the core idea.