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 Binding:
$container->set('myService', function() {
return new MyService();
});
$service = $container->get('myService');
Configuration via Class:
use Aura\Di\ContainerConfig;
class AppConfig implements ContainerConfig
{
public function define(Aura\Di\Container $di)
{
$di->params[\MyService::class]['param1'] = 'value1';
$di->set('myService', \MyService::class);
}
}
$builder = new ContainerBuilder();
$container = $builder->newInstance(new AppConfig());
ContainerBuilder for creating and configuring containers.Container for retrieving services and managing bindings.#[Service], #[Instance]).Use attributes to define services declaratively:
use Aura\Di\Attribute\Service;
#[Service]
class MyService {
public function __construct(private string $name) {}
}
// Scan and compile attributes into blueprints:
$builder = new ContainerBuilder();
$builder->scan([__DIR__ . '/src']);
$container = $builder->newInstance();
Key Attributes:
#[Service]: Marks a class as a service.#[Instance]: Injects an existing instance.#[Value]: Injects a scalar value.#[Blueprint]: Compiles a class into a blueprint.Defer instantiation until first use:
$container->lazy('expensiveService', function() {
return new ExpensiveService();
});
$service = $container->lazyGet('expensiveService'); // Instantiated on first call
Lazy Types:
LazyValue: Scalar values.LazyCallable: Callables.LazyArray: Arrays of lazy values.Pass parameters dynamically:
$di->params[\MyService::class]['context'] = $context;
$service = $di->get(\MyService::class);
Reuse instances across requests (e.g., for HTTP handlers):
$builder->setProducer('requestHandler', function() {
return new RequestHandler();
});
Pre-generate blueprints for performance:
$builder->scan([__DIR__ . '/src']);
$builder->compileToFile(__DIR__ . '/var/blueprints.php');
$container = include __DIR__ . '/var/blueprints.php';
Service Provider Setup:
use Aura\Di\ContainerBuilder;
use Illuminate\Support\ServiceProvider;
class AuraDiServiceProvider extends ServiceProvider
{
public function register()
{
$builder = new ContainerBuilder();
$builder->scan([app_path('Config')]);
$this->app->singleton('aura.di', function() use ($builder) {
return $builder->newInstance();
});
}
}
Binding Laravel Services:
$container = app('aura.di');
$container->set('router', function() {
return app('router');
});
Resolving Dependencies:
$service = $container->get('myService');
AbstractContainerConfigTest for unit testing configurations:
use Aura\Di\AbstractContainerConfigTest;
class MyConfigTest extends AbstractContainerConfigTest
{
protected function getConfigClass(): string
{
return AppConfig::class;
}
}
Automatically discover and configure classes in a directory:
$builder->scan([
__DIR__ . '/src',
__DIR__ . '/config',
]);
Auto-Resolution Locking:
get() or newInstance() before finishing configuration.lazyGet() or lazyNewInstance() to defer locking.Circular Dependencies:
CircularReferenceException for circular dependencies.set() with a factory.Attribute Scanning Quirks:
Serialization:
compileToFile() for persistent containers.PHP 8 Attributes:
#[Service] must target TARGET_CLASS or TARGET_PROPERTY (fixed in v5.0.0-alpha.2).Enable Debug Mode:
$builder->setDebug(true);
Inspect Blueprints:
$blueprints = $builder->getBlueprints();
print_r($blueprints);
Check Class Map:
$classMap = $builder->getClassMap();
if (!$classMap->hasClass(MyService::class)) {
// Class not found in scan
}
Lazy Resolution Issues:
lazyLazy() to create directly invokable lazies:
$lazy = $container->lazyLazy('service');
$instance = $lazy(); // Invokes lazy
Custom Attribute Configs:
Implement AttributeConfigInterface to handle custom attributes:
use Aura\Di\AttributeConfigInterface;
class MyAttributeConfig implements AttributeConfigInterface
{
public function configure(Aura\Di\Container $di, array $attributes)
{
// Custom logic
}
}
Container Compilation Hooks:
Implement ContainerCompileInterface:
use Aura\Di\ContainerCompileInterface;
class MyCompiler implements ContainerCompileInterface
{
public function compile(Aura\Di\ContainerBuilder $builder)
{
// Modify blueprints before compilation
}
}
Custom Resolver: Replace the default resolver for advanced control:
$builder->setResolver(new MyCustomResolver());
Attribute Targets:
#[Service], #[Instance], and #[Value] must target TARGET_PROPERTY for constructor promotion (PHP 8.0+).Scanner Exclusions:
#[CompileNamespace] to exclude namespaces from compilation.Class Map Updates:
$builder->getClassMap()->clear();
PHP 8.4+ Attributes:
Compile for Production:
$builder->compileToFile(__DIR__ . '/var/production_blueprints.php');
Avoid Lazy Overhead:
set() for singletons or frequently used services.Batch Scanning:
How can I help you explore Laravel packages today?