yiisoft/injector
yiisoft/injector is a lightweight PHP dependency injection container for building objects and wiring dependencies via constructor, method, and property injection. Supports factories, config-based definitions, and PSR-friendly integration for Yii apps and beyond.
Start by installing via Composer: composer require yiisoft/injector. The core class is Yiisoft\Injector\Injector, which you instantiate with optional configuration. Its simplest use case is automatic constructor injection—just call $injector->get(MyService::class) and it will resolve all constructor dependencies via reflection. For quick prototyping or small apps, this zero-configuration autowiring is often enough. Check the src/Injector.php source file first for signature clarity; the constructor signature is public function __construct(array $definitions = []), so begin defining overrides where needed (e.g., Injector::class => Injector::class for self-reference, or service interfaces to concrete implementations). No bootstrap file is strictly required—you can instantiate per-request or as a singleton in your app.
$injector->get(SomeServiceInterface::class) in factories or controllers to obtain interface-typed services. Combine with typed properties (PHP 8+) for cleaner controllers: public function __construct(private SomeServiceInterface $service) {}.[LoggerInterface::class => fn() => new FileLogger('app.log')]. Use Injector::build() to create partial definitions.[CachedClient::class => fn(Injector $injector) => new CachedClient($injector->get(HttpClient::class))].lazy() (via Injector::lazy() helper) to defer instantiation until accessed.$injector->invoke([$service, 'methodName']) to inject arguments into non-constructor methods—useful for event handlers or console commands.yiisoft/injector-compatible constructors (type-hinted, no hardcoded dependencies), enabling downstream apps to wire services without vendor lock-in.CircularReferenceException), but it doesn’t resolve them. Design with constructor immutability and prefer composition over deep chains.public and properties use setter injection if needed (though not auto-wired). Use Injector::with() to customize reflection behavior if extending the package.get() throws an NotFoundException or AmbiguousDependencyException, inspect the stack trace—the message includes the missing interface/concrete class and the class requesting it. Enable DEBUG mode (if available in your version) to see full resolution paths.get() call unless the definition is cached manually (e.g., via Injector::build() + serialize()/unserialize()). For production, pre-build and cache the injector configuration.Injector to add custom resolution logic (e.g., support for custom attributes), but prefer composition (e.g., middleware-like decorators) where possible—this package is designed to stay lean.How can I help you explore Laravel packages today?