symfony/dependency-injection
Symfony DependencyInjection standardizes and centralizes object construction with a powerful service container. Define services and parameters, manage autowiring and configuration, and optimize performance through compilation for cleaner, decoupled apps.
Installation:
composer require symfony/dependency-injection
Laravel already includes this package as part of its core, so no additional installation is needed.
First Use Case:
// In a service class
public function __construct(private MyDependency $dependency) {}
// Laravel will automatically inject `MyDependency` if it's registered.
Where to Look First:
Illuminate\Container\Container (extends Symfony\Component\DependencyInjection\ContainerInterface).config/app.php defines service bindings and providers.Service Binding and Resolution:
$container->bind('MyService', function ($container) {
return new MyService($container->make('AnotherService'));
});
config/app.php:
'providers' => [
Illuminate\Foundation\ProviderRepository::class,
],
'aliases' => [],
'bindings' => [],
'singletons' => [],
'whenLoadingConfig' => [],
'autowire' => true, // Enable autowiring
'apiResources' => [],
'except' => [],
'caching' => false,
'terminate' => [],
'namespace' => 'App\\',
Tagging and Collecting Services:
register method:
$this->app->tag(['firstService', 'secondService'], 'my.tag');
$services = $this->app->tagged('my.tag');
Lazy Loading and Proxies:
lazy() to defer instantiation:
$container->bind('LazyService', function () {
return new LazyService();
})->setLazy(true);
singleton() method also supports lazy loading.Context and Scopes:
Illuminate\Contracts\Container\ScopedBinding):
$container->bind('ScopedService', ScopedService::class)->in('scoped');
Parameter Bag:
config/app.php or environment files:
$container->setParameter('app.name', 'MyApp');
$name = $container->getParameter('app.name');
Extension and Compilation:
public function register()
{
$this->app->singleton('MyService', function ($app) {
return new MyService($app->make('AnotherService'));
});
}
Attribute-Based Configuration:
#[Target] to configure services:
use Symfony\Component\DependencyInjection\Attribute\Target;
class MyService {
#[Target('app.name')]
public function setName(string $name) {}
}
Circular Dependencies:
Service Overwriting:
bind() followed by singleton()) will overwrite the previous binding. Use extend() to modify existing bindings without replacing them.Lazy Loading Quirks:
Tagged Services and Priorities:
PriorityTaggedServiceTrait or custom sorting if order matters:
$services = $this->app->tagged('my.tag')->sort(function ($a, $b) {
return strcmp($a['priority'], $b['priority']);
});
Environment Variables in Config:
env() helper or bind them as parameters:
$container->setParameter('app.debug', env('APP_DEBUG', false));
Deprecated Features:
PhpDumper) may not work as expected in Laravel’s context. Prefer Laravel’s native solutions (e.g., php artisan optimize).Type Safety:
#[AutowireCallable] for stricter control:
#[AutowireCallable]
public function __construct(private MyService $service) {}
Dump Container Contents:
php artisan container:dump (custom command) or inspect the container manually:
dd($this->app->getBindings());
Check for Missing Bindings:
APP_DEBUG=true) to get detailed errors for unresolved dependencies.Service Existence:
if ($this->app->bound('MyService')) {
$service = $this->app->make('MyService');
}
Parameter Validation:
register method of service providers to catch misconfigurations.Custom Compilers:
Compiler pass:
$this->app->resolving('MyService', function ($service, $app) {
// Post-resolution logic
});
Dynamic Bindings:
$this->app->bind('DynamicService', function ($app) {
return new DynamicService($app['config']['dynamic.value']);
});
Interface Binding:
$this->app->bind(
Illuminate\Contracts\Auth\Authenticatable::class,
App\Models\User::class
);
Event Listeners:
Illuminate\Container\Events\BindingResolved):
$this->app->resolved('MyService', function ($service) {
// Logic after service resolution
});
Custom Container:
Illuminate\Container\Container and override methods like make() or bind().How can I help you explore Laravel packages today?