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
|
↓
OrderControllerSo when Laravel sees:
PaymentService $paymentit 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
↓
PaymentServiceLaravel 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
↓
ApiClientYou 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 ControllerThat'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 Service6. Remember these three things
This is the most important part for your interview:
Service Container
Manages and creates objects/dependencies.
Container → creates PaymentServiceDependency 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.