A container is like a smart assistant or factory that knows how to build and provide anything your app needs—without you doing all the setup manually.
We already learn that idea: https://dilip-parmar.in/mvc-lesson-11-dependency-injection-di-container-using-a-very-simple-real-life-analogy/
So it is a tool for automatic dependency injection — it figures out what your class needs and provides it.
Laravel’s container is based on the Inversion of Control (IoC) principle — instead of your classes creating dependencies themselves, the container provides them.
✅ Why Learn illuminate/container First?
Everything in Laravel goes through the container:
- Controllers
- Middleware
- Event listeners
- Artisan commands
- Route callbacks with parameters
- Jobs, services, notifications…
So if you understand the container, you can understand how Laravel resolves and injects dependencies everywhere.
📚 Let’s Break Down Key Concepts to Learn:
1. 🔗 Binding and Resolving Classes
👉 Binding: Tell the container how to build a class
$container->bind('foo', function () {
return new FooService();
});
OR
// Bind a "mailer" class to the container
$container->bind('mailer', function ($container) {
$mailer = new Acme\Mailer;
$mailer->username = 'username';
$mailer->password = 'password';
$mailer->from = 'foo@bar.com';
return $mailer;
});
When you say
$container->make('foo'), it will call the closure and returnnew FooService().
You can also bind by class name:
$container->bind(FooService::class, function () {
return new FooService();
});
So bind() is a method where we define how to build an object.
👉 Resolving: Ask the container to give you the instance
make() is also a method which Build an object with all its dependencies
$foo = $container->make('foo'); // Returns a FooService instance
OR
$mailer = $container->make('mailer');
// Set mail settings
$mailer->to = 'foo@bar.com';
$mailer->subject = 'Test email';
$mailer->body = 'This is a test email.';
// Send the email
if ($mailer->send()) {
$response->getBody()->write('Email successfully sent!');
}
2. 🔁 Singleton Bindings
Sometimes you only want one instance shared across your app (like a shared cache or config class).
// Bind a shared "database" class to the container
$container->singleton('database', function ($container) {
return new Acme\Database('username', 'password', 'host', 'database');
});
Now every time you call $container->make('config'), it returns the same instance.
🧠 Singleton = cache the instance after the first time.
3. 🧱 Automatic Dependency Injection (Magic of make())
The container is smart. If a class has dependencies, it can figure them out automatically if those dependencies are also bound or resolvable.
Example:
namespace App\Services;
use \Illuminate\Mail\Mailer;
class MyService
{
public function __construct(Mailer $mailer) {
$this->mailer = new Mailer;
}
}
The make method will return an instance of the class or interface you request. Where you request to make an interface, Laravel will lookup a binding for that interface to a concrete class.
$app->make('App\Services\MyService'); // new \App\Services\MyService.
One advantage to using the make method, is that Laravel will automatically inject any dependencies the class may define in it’s constructor.
E.g. an instance of the Mailer class would be automatically injected here.
Sometimes you may found this:
$container->bind('template', \Acme\Template::class);
And Laravel treats it as: Both do the same thing — Laravel just makes it easier to use class names directly. This means: “Register this class into the container so Laravel knows how to make it later.”
Check this for a full example: https://github.com/mikegsmith76/laravel-standalone/blob/master/components/container/index.php
$container->bind('template', function ($container) {
return $container->make(\Acme\Template::class);
});
🔁 Summary
| Concept | What it Means | Why it Matters |
|---|---|---|
bind() | Define how to build an object | Control construction logic |
singleton() | Share the same instance | For memory/caching/performance |
make() | Build an object with all its dependencies | Auto-wires everything |
| Constructor Injection | Inject dependencies into constructor | Clean, testable code |
| Service Providers | Organize bindings | Used by Laravel apps |
