A modern, high-performance, PSR-11 compatible Dependency Injection Container for PHP 8.5+, built for real-world dependency graphs — including circular dependencies — with a clean, pipeline-based resolution engine.
Existing containers (Symfony DI, PHP-DI, Laravel Container) are excellent, but they share a common limitation: constructor-only injection cannot cleanly solve circular dependency graphs without resorting to opaque proxy magic. Aicrion Container solves this natively with a lifecycle-based injection model:
instantiate()— the object is created (constructor injection happens here).injectDependencies()— post-construction injection, safe for circular graphs.onReady()— a lifecycle hook fired once, after all injection is complete.
- PSR-11
ContainerInterfacecompliant - Constructor injection with automatic reflection-based resolution
- Post-construction injection for circular dependency graphs
- Service lifecycle:
instantiate → injectDependencies → onReady - Singletons, factories, transients, scoped services
- Aliases, tags/groups, decorators (
extend) - Lazy loading via virtual proxies
- Attributes:
#[Inject],#[Singleton],#[Factory],#[Bind],#[Tag],#[Lazy] - Pipeline-based, fully extensible resolution engine
- Before/after resolve hooks
- Dependency graph analyzer (export to DOT/Graphviz)
- Beautiful, actionable exceptions
- Container compilation for reflection-free production performance
- Child containers with scoped overrides
- Contextual binding (
when()->needs()->give()) - Service providers with register/boot lifecycle
- WeakMap-backed scoped services (auto-released, no manual reset)
- CLI tools:
container-inspect,container-warmup #[Autowire]for fine-grained parameter/property overrides (services, env vars, literals)#[Autoconfigure]for interface-driven tagging and lifetime configuration
composer require aicrion/containeruse Aicrion\Container\Container;
$container = new Container();
$container->singleton(Logger::class);
$container->bind(LoggerInterface::class, Logger::class);
$container->alias('logger', LoggerInterface::class);
$userService = $container->make(UserService::class);use Aicrion\Container\Service;
class ServiceA extends Service
{
public ServiceB $b;
public function injectDependencies(ServiceB $b): void
{
$this->b = $b;
}
}
class ServiceB extends Service
{
public ServiceA $a;
public function injectDependencies(ServiceA $a): void
{
$this->a = $a;
}
}
$container->singleton(ServiceA::class);
$container->singleton(ServiceB::class);
$a = $container->make(ServiceA::class); // fully wired, no exceptionsFull documentation is available at https://aicrion.github.io/container-php/ and in the docs directory.
MIT © Hadi Akbarzadeh
Aicrion Container was benchmarked against Symfony DependencyInjection, PHP-DI, and Laravel's Illuminate Container on the same PHP 8.5.8 machine (10,000 revs x 5 iterations per subject). Full methodology and raw output: benchmarks/RESULTS.md.
Live resolution (no ahead-of-time compilation):
| Container | Constructor injection | Singleton lookup |
|---|---|---|
| Symfony DependencyInjection | 0.195us | 0.190us |
| PHP-DI | 1.478us | -- |
| Laravel Illuminate Container | 2.546us | 0.316us |
| Aicrion Container | 5.616us | 1.510us |
Compiled resolution (ahead-of-time optimization):
| Container | Constructor injection | Singleton lookup |
|---|---|---|
| Symfony DependencyInjection (compiled) | 0.183us | 0.183us |
| Aicrion Container (compiled) | 0.599us | 0.283us |
Compiling Aicrion Container's definitions delivers a ~9.4x speedup on constructor injection and ~5.3x on singleton lookups over live reflection-based resolution.
Run the benchmarks yourself:
composer install
composer benchmark