aura/di
Aura.Di is a PSR-11 dependency injection container for PHP 8+ with constructor and setter injection, interface and trait awareness, configurable wiring with inheritance, and support for serialization. Installable via Composer and fully documented.
Installation:
composer require aura/di
Basic Container Initialization:
use Aura\Di\Container;
use Aura\Di\ContainerBuilder;
$builder = new ContainerBuilder();
$container = $builder->newInstance();
First Use Case: Manual Service Registration
$container->set('serviceName', function ($di) {
return new MyService($di->get('dependency'));
});
First Use Case: Attribute-Based Configuration (PHP 8.0+)
use Aura\Di\Inject;
class MyService {
public function __construct(
#[Inject] private MyDependency $dependency
) {}
}
// Configure scanner (see Implementation Patterns)
index.md and migrating.md for 5.x changes).src/ for core classes (Container, ContainerBuilder, Inject attribute).tests/ for usage examples and edge cases.#[Inject], #[Service], #[Value]).
use Aura\Di\Inject;
class UserRepository {
public function __construct(
#[Inject] private DatabaseConnection $db,
#[Inject] private LoggerInterface $logger
) {}
}
use Aura\Di\Scanner\Scanner;
use Aura\Di\Scanner\ClassScannerConfig;
$scanner = new Scanner();
$scanner->findClassesIn(__DIR__.'/App/Services');
$scanner->scan($container);
use Aura\Di\ContainerConfig;
class AppConfig implements ContainerConfig {
public function define(Aura\Di\Container $di): void {
$di->params['UserRepository'][0] = $di->lazyNew('DatabaseConnection');
$di->params['UserRepository'][1] = $di->lazyNew('Logger');
}
}
$builder = new ContainerBuilder();
$container = $builder->newInstance([AppConfig::class]);
$container->lazyNew('ExpensiveService'); // Returns a LazyInterface
$service = $container->get('ExpensiveService'); // Instantiates on demand
$di->params['UserService']['locale'] = $di->lazyGet('Request')->lazyCall('getLocale');
use Illuminate\Support\ServiceProvider;
class AuraDiServiceProvider extends ServiceProvider {
public function register() {
$this->app->singleton('aura.di', function () {
$builder = new ContainerBuilder();
return $builder->newInstance([AppConfig::class]);
});
}
}
$this->app->make('aura.di')->get('UserRepository');
use Aura\Di\Scanner\Compiler;
$compiler = new Compiler();
$compiler->compile($container, __DIR__.'/var/cache');
$container = ContainerBuilder::fromFile(__DIR__.'/var/cache/compiled.php');
AppServiceProvider:
public function boot() {
$this->app->singleton('container', function () {
$builder = new ContainerBuilder();
return $builder->newInstance([AppConfig::class]);
});
}
Illuminate\Contracts\Container).$auraDi = $this->app->make('aura.di');
$userRepo = $auraDi->get('UserRepository');
use Aura\Di\Container;
use Orchestra\Testbench\OverrideBindings;
public function setUp(): void {
parent::setUp();
$this->app->instance('container', new Container());
}
$serialized = serialize($container);
file_put_contents('cache/container.ser', $serialized);
// Later...
$container = unserialize(file_get_contents('cache/container.ser'));
Aura\Di\Exception\CircularReference).$container->setAutoResolve('MyService', false);
AppConfig:
$di->setAutoResolve(false);
$scanner->findClassesIn([
__DIR__.'/App',
__DIR__.'/Modules',
]);
$scanner->getClassMap()->hasClass('My\Namespace\Class');
rm -rf var/cache && php artisan aura:compile
use Aura\Di\Scanner\Compiler;
use Illuminate\Console\Command;
class CompileAuraDi extends Command {
protected $signature = 'aura:compile';
public function handle() {
$compiler = new Compiler();
$compiler->compile($this->app->make('aura.di'), storage_path('framework/cache'));
}
}
#[Service] must target TARGET_PROPERTY for constructor promotion:
#[Service(target: Attribute::TARGET_PROPERTY)]
public function __construct(private Database $db) {}
lazyLazy() for debugging:
$container->lazyLazy('MyService')->__invoke(); // Force resolution
$scanner->setLogger(new \Monolog\Logger('scanner', [
new \Monolog\Handler\StreamHandler(__DIR__.'/scanner.log', \Monolog\Logger::DEBUG),
]));
print_r($container->getParams());
$container->has('MyService'); // Returns bool
try {
$service = $container->get('MyService');
} catch (\ReflectionException $e) {
Log::
How can I help you explore Laravel packages today?