Mastering Laravel’s Service Container: Dependency Injection and Advanced Binding Techniques
This guide explains Laravel's service container fundamentals, showing how to inject dependencies, bind services, use singletons, contextual bindings, tags, extend services, resolve instances, and listen to container events for building robust PHP back‑end applications.
Service Container Overview
Laravel's service container manages class dependencies and performs dependency injection, allowing objects to be supplied via constructors or setter methods.
Simple Example
<?php
namespace App\Http\Controllers;
use App\User;
use App\Repositories\UserRepository;
use App\Http\Controllers\Controller;
class UserController extends Controller {
/**
* The user repository implementation.
* @var UserRepository
*/
protected $users;
/**
* Create a new controller instance.
* @param UserRepository $users
*/
public function __construct(UserRepository $users) {
$this->users = $users;
}
/**
* Show the specified user's profile.
* @param int $id
* @return Response
*/
public function show($id) {
$user = $this->users->find($id);
return view('user.profile', ['user' => $user]);
}
}The controller receives a UserRepository instance via injection, making it easy to swap implementations or mock the repository during testing.
Service Binding
Basic Binding
Tip: If a class does not depend on an interface, you do not need to bind it; the container can resolve it automatically via reflection.
Simple Binding
$this->app->bind('HelpSpot\API', function ($app) {
return new HelpSpot\API($app->make('HttpClient'));
});Singleton Binding
$this->app->singleton('HelpSpot\API', function ($app) {
return new HelpSpot\API($app->make('HttpClient'));
});Instance Binding
$api = new HelpSpot\API(new HttpClient);
$this->app->instance('HelpSpot\API', $api);Binding Primitive Values
$this->app->when('App\Http\Controllers\UserController')
->needs('$variableName')
->give($value);Binding Interfaces to Implementations
$this->app->bind('App\Contracts\EventPusher', 'App\Services\RedisEventPusher');When a class type‑hints EventPusher, the container injects a RedisEventPusher instance.
Contextual Binding
use Illuminate\Support\Facades\Storage;
use App\Http\Controllers\PhotoController;
use App\Http\Controllers\VideoController;
use Illuminate\Contracts\Filesystem\Filesystem;
$this->app->when(PhotoController::class)
->needs(Filesystem::class)
->give(function () { return Storage::disk('local'); });
$this->app->when([VideoController::class, UploadController::class])
->needs(Filesystem::class)
->give(function () { return Storage::disk('s3'); });Tagging Bindings
$this->app->bind('SpeedReport', function () { /* ... */ });
$this->app->bind('MemoryReport', function () { /* ... */ });
$this->app->tag(['SpeedReport', 'MemoryReport'], 'reports');
$this->app->bind('ReportAggregator', function ($app) {
return new ReportAggregator($app->tagged('reports'));
});Extending Bindings
$this->app->extend(Service::class, function ($service) {
return new DecoratedService($service);
});Resolving Instances
make Method
$api = $this->app->make('HelpSpot\API');If the container instance is not directly accessible, use the global helper:
$api = resolve('HelpSpot\API');makeWith Method (Injecting Parameters)
$api = $this->app->makeWith('HelpSpot\API', ['id' => 1]);Automatic Injection
Laravel automatically resolves type‑hinted dependencies for controllers, listeners, jobs, middleware, etc.
<?php
namespace App\Http\Controllers;
use App\Users\Repository as UserRepository;
class UserController extends Controller {
protected $users;
public function __construct(UserRepository $users) {
$this->users = $users;
}
public function show($id) {
// ...
}
}Container Events
The container fires a resolving event each time it resolves an object. You can listen globally or for a specific class:
$this->app->resolving(function ($object, $app) {
// Called for any resolved object
});
$this->app->resolving(HelpSpot\API::class, function ($api, $app) {
// Called only for HelpSpot\API instances
});These callbacks allow you to modify objects before they are returned to the caller.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Laravel Tech Community
Specializing in Laravel development, we continuously publish fresh content and grow alongside the elegant, stable Laravel framework.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
