illuminate/container
Illuminate Container is Laravel’s lightweight dependency injection container for resolving classes, managing bindings, singletons, contextual dependencies, and automatic constructor injection. It powers service resolution and inversion of control in Laravel apps and packages.
Start by installing the package via Composer (composer require illuminate/container) or using it within a Laravel app (it’s bundled in laravel/framework). Begin with resolving a simple class:
$container = new Illuminate\Container\Container();
$container->bind(\Psr\Log\LoggerInterface::class, \App\Logging\ConsoleLogger::class);
$logger = $container->make(\Psr\Log\LoggerInterface::class);
Explore the API by checking bind(), singleton(), instance(), make(), and resolve() — these cover 90% of day-to-day usage. Use Container::getInstance() only when globally sharing a single container instance.
bind(NotificationSenderInterface::class, SlackSender::class)). Resolve them anywhere via make() or constructor injection.when(...)->needs(...)->give(...) to inject different implementations based on consumer class (e.g., production vs. staging storage for a StorageInterface in UploadController vs. ImportController).$container->tag('formatter', [JsonFormatter::class, XmlFormatter::class])) and resolve all at once ($container->tagged('formatter')), ideal for extension points like event listeners or formatters.call(): Resolve dependencies dynamically for callbacks (e.g., $container->call([$controller, 'index'])) — crucial for event dispatching, CLI commands, and custom routing.extend() to wrap resolved services (e.g., add logging, caching, or retries) without modifying the original class:
$container->extend(ApiClient::class, function ($client, $container) {
return new RetryDecorator($client);
});
Container::setInstance() affects the entire process — dangerous in CLI workers (e.g., Horizon, queue listeners). Prefer local containers or explicit instantiation unless resetting context intentionally.CircularDependencyException at resolve time — prevent by injecting interfaces, using lazy proxies, or deferring with make() in the constructor.makeWith() or contextual needs('$variable')->give($value) when constructor parameters aren’t type-hinted or vary at runtime (e.g., injecting a config key or dynamic ID).Psr\Container\ContainerInterface, Laravel-specific methods like tag(), extend(), build() won’t work outside Laravel — avoid relying on them for portability.resolved($abstract) tells if a binding is already instantiated, and build() lets you inspect how a class would be resolved (useful for debugging missing bindings or double resolution).resolver or override make() / build() for cross-cutting concerns (e.g., auto-instrumentation, lazy-loading proxies, or DI tracing).How can I help you explore Laravel packages today?