Skip to content

Repository files navigation

Aicrion Container

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.

License: MIT PHP Version

Why another container?

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:

  1. instantiate() — the object is created (constructor injection happens here).
  2. injectDependencies() — post-construction injection, safe for circular graphs.
  3. onReady() — a lifecycle hook fired once, after all injection is complete.

Features

  • PSR-11 ContainerInterface compliant
  • 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

Quick start

composer require aicrion/container
use 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);

Solving circular dependencies

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 exceptions

Documentation

Full documentation is available at https://aicrion.github.io/container-php/ and in the docs directory.

License

MIT © Hadi Akbarzadeh

Benchmarks

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

Releases

Packages

Contributors

Languages