### Quick Start Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md A basic example of setting up and using the Wirebox container. ```php use AsceticSoft\Wirebox\ContainerBuilder; $builder = new ContainerBuilder(projectDir: __DIR__); // Scan a directory — all concrete classes are auto-registered $builder->scan(__DIR__ . '/src'); // Build the container $container = $builder->build(); // Resolve any service $service = $container->get(App\UserService::class); ``` -------------------------------- ### Full Example Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md A complete example demonstrating how to configure and use the Wirebox container, including excluding directories, scanning for classes, explicit bindings, environment-based parameters, custom factories, and building the container. ```php // bootstrap.php use AsceticSoft\Wirebox\ContainerBuilder; $builder = new ContainerBuilder(projectDir: __DIR__); // Exclude entities and migrations from the container $builder->exclude('Entity/*'); $builder->exclude('Migration/*'); // Scan application classes $builder->scan(__DIR__ . '/src'); // Explicit bindings where needed $builder->bind(LoggerInterface::class, FileLogger::class); $builder->bind(CacheInterface::class, RedisCache::class); // Environment-based parameters $builder->parameter('db.host', '%env(DB_HOST)%'); $builder->parameter('db.port', '%env(int:DB_PORT)%'); $builder->parameter('app.debug', '%env(bool:APP_DEBUG)%'); // Custom factory $builder->register(PDO::class, function ($c) { return new PDO( sprintf('mysql:host=%s;port=%d;dbname=app', $c->getParameter('db.host'), $c->getParameter('db.port'), ), ); }); // Build and use $container = $builder->build(); $app = $container->get(App\Kernel::class); $app->run(); ``` -------------------------------- ### Installation Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Install Wirebox using Composer. ```bash composer require ascetic-soft/wirebox ``` -------------------------------- ### CQRS Example - Interface Definitions Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Defines CommandHandlerInterface and QueryHandlerInterface with #[AutoconfigureTag] for CQRS setup. ```php use AsceticSoft\Wirebox\Attribute\AutoconfigureTag; #[AutoconfigureTag('command.handler')] interface CommandHandlerInterface { public function __invoke(object $command): void; } #[AutoconfigureTag('query.handler')] interface QueryHandlerInterface { public function __invoke(object $query): mixed; } // Handlers — no manual tagging needed class CreateUserHandler implements CommandHandlerInterface { public function __invoke(object $command): void { /* ... */ } } class DeleteUserHandler implements CommandHandlerInterface { public function __invoke(object $command): void { /* ... */ } } class GetUserHandler implements QueryHandlerInterface { public function __invoke(object $query): mixed { /* ... */ } } ``` -------------------------------- ### .env File Format Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Example of the .env file format. ```env APP_NAME=Wirebox DB_HOST=localhost DB_PORT=5432 APP_DEBUG=true # Comments are supported QUOTED="hello world" SINGLE='literal value' # Variable interpolation BASE_PATH=/opt FULL_PATH="${BASE_PATH}/app" # Export prefix is stripped export SECRET_KEY=abc123 ``` -------------------------------- ### CQRS Example - Container Build and Retrieval Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Demonstrates building the container and retrieving tagged services for CQRS handlers. ```php $builder = new ContainerBuilder(projectDir: __DIR__); $builder->scan(__DIR__ . '/src'); // No need for bind() — CommandHandlerInterface is autoconfigured $container = $builder->build(); // Iterate all command handlers foreach ($container->getTagged('command.handler') as $handler) { // CreateUserHandler, DeleteUserHandler } // Iterate all query handlers foreach ($container->getTagged('query.handler') as $handler) { // GetUserHandler } ``` -------------------------------- ### Testing Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Commands to install dependencies and run tests using PHPUnit. ```bash composer install vendor/bin/phpunit ``` -------------------------------- ### Compiling the Container Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Example of building a container, scanning for services, binding interfaces, setting parameters, and compiling it to a PHP class for production. ```php $builder = new ContainerBuilder(projectDir: __DIR__); $builder->scan(__DIR__ . '/src'); $builder->bind(LoggerInterface::class, FileLogger::class); $builder->parameter('db.host', '%env(DB_HOST)%'); // Generate the compiled container $builder->compile( outputPath: __DIR__ . '/var/cache/CompiledContainer.php', className: 'CompiledContainer', namespace: 'App\Cache', ); ``` -------------------------------- ### Retrieve Tagged Services Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Example of retrieving services by tag. ```php foreach ($container->getTagged('event.listener') as $listener) { $listener->handle($event); } ``` -------------------------------- ### Safe Circular Dependency Example Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Illustrates a safe circular dependency scenario where both services are lazy singletons, demonstrating how Wirebox handles it. ```php // Safe — both are lazy singletons (the default) #[Lazy] class ServiceA { public function __construct(public readonly ServiceB $b) {} } #[Lazy] class ServiceB { public function __construct(public readonly ServiceA $a) {} } $container = $builder->build(); // OK $a = $container->get(ServiceA::class); assert($a->b->a === $a); // same proxy ``` -------------------------------- ### Programmatic Autoconfiguration Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Example of using registerForAutoconfiguration() for more control over autoconfiguration, including lifetime, lazy loading, and multiple tags. ```php $builder->registerForAutoconfiguration(EventListenerInterface::class) ->tag('event.listener') ->singleton() ->lazy(); ``` ```php $builder->registerForAutoconfiguration(AsScheduled::class) ->tag('scheduler.task') ->transient(); ``` -------------------------------- ### #[Transient] Attribute Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md A new instance is created on every get() call. ```php use AsceticSoft\Wirebox\Attribute\Transient; #[Transient] class RequestContext { } ``` -------------------------------- ### Tagged Services Container API Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Example of retrieving all services tagged with a specific identifier. ```php $loggers = $container->getTagged('logger'); // iterable ``` -------------------------------- ### Handling Circular Dependency Exception Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Example of catching a `CircularDependencyException` when an unsafe circular dependency is detected. ```php use AsceticSoft\Wirebox\Exception\CircularDependencyException; try { $builder->build(); } catch (CircularDependencyException $e) { // "Circular dependency detected: ServiceA -> ServiceB -> ServiceA. ..." echo $e->getMessage(); } ``` -------------------------------- ### Inject Attribute Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Example of using the #[Inject] attribute to specify a concrete implementation for a type-hinted constructor parameter. ```php use AsceticSoft\Wirebox\Attribute\Inject; class NotificationService { public function __construct( #[Inject(SmtpMailer::class)] private MailerInterface $mailer, ) { } } ``` -------------------------------- ### ContainerBuilder Initialization Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Initialize the ContainerBuilder with the project directory. ```php $builder = new ContainerBuilder(projectDir: __DIR__); ``` -------------------------------- ### AutoconfigureTag on Interface Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Demonstrates how to use #[AutoconfigureTag] on an interface to automatically tag all implementing classes. ```php use AsceticSoft\Wirebox\Attribute\AutoconfigureTag; #[AutoconfigureTag('command.handler')] interface CommandHandlerInterface { public function __invoke(object $command): void; } // Automatically receives the 'command.handler' tag when scanned class CreateUserHandler implements CommandHandlerInterface { public function __invoke(object $command): void { // ... } } ``` -------------------------------- ### Using the Compiled Container Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md How to include and instantiate the compiled container in a production environment. ```php require_once __DIR__ . '/var/cache/CompiledContainer.php'; $container = new App\Cache\CompiledContainer(); $service = $container->get(UserService::class); ``` -------------------------------- ### Service Registration with Type Hinting Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Demonstrates how a service can register itself under multiple keys (PSR-11, Wirebox extended contract) and how to type-hint them. ```php use Psr\Container\ContainerInterface; use AsceticSoft\Wirebox\WireboxContainerInterface; class ServiceLocator { public function __construct( // Any of the three works: private ContainerInterface $psr, // PSR-11 private WireboxContainerInterface $wirebox // Wirebox extended contract ) { } } ``` -------------------------------- ### Focusing a Single Test Source: https://github.com/ascetic-soft/wirebox/blob/main/AGENTS.md How to run a specific PHPUnit test. ```bash vendor/bin/phpunit --filter ``` -------------------------------- ### Repeatable AutoconfigureTag Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Illustrates applying multiple #[AutoconfigureTag] attributes to a single interface. ```php #[AutoconfigureTag('command.handler')] #[AutoconfigureTag('auditable')] interface CommandHandlerInterface {} ``` -------------------------------- ### Parameters Container API Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Demonstrates retrieving specific parameters or all parameters from the container. ```php $host = $container->getParameter('db.host'); $all = $container->getParameters(); ``` -------------------------------- ### Workflow Commands Source: https://github.com/ascetic-soft/wirebox/blob/main/AGENTS.md Common make commands for local development and testing. ```bash make install make check make fix-dry make fix make stan make test ``` -------------------------------- ### Parameters and Environment Variables Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Set parameters that can reference environment variables. ```php $builder->parameter('db.host', '%env(DB_HOST)%'); $builder->parameter('db.port', '%env(int:DB_PORT)%'); $builder->parameter('app.debug', '%env(bool:APP_DEBUG)%'); $builder->parameter('rate.limit', '%env(float:RATE_LIMIT)%'); ``` -------------------------------- ### Fluent API Eager Configuration Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md The same behavior as #[Eager] is available via the fluent API. ```php $builder->register(AppConfig::class)->eager(); ``` -------------------------------- ### AutoconfigureTag on Custom Attribute Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Shows how to use #[AutoconfigureTag] on a custom attribute to tag classes decorated with it. ```php use AsceticSoft\Wirebox\Attribute\AutoconfigureTag; #[Attribute(Attribute::TARGET_CLASS)] #[AutoconfigureTag('scheduler.task')] class AsScheduled {} // Automatically receives the 'scheduler.task' tag when scanned #[AsScheduled] class DailyReportTask { public function run(): void { /* ... */ } } ``` -------------------------------- ### Fluent API Lazy Configuration Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md The same behavior as #[Lazy] is available via the fluent API. ```php $builder->register(HeavyReportGenerator::class)->lazy(); ``` -------------------------------- ### #[Singleton] Attribute Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Marks a class as singleton (this is the default behavior, use for explicitness). ```php use AsceticSoft\Wirebox\Attribute\Singleton; #[Singleton] class DatabaseConnection { } ``` -------------------------------- ### Production: composer dump-env Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md For production, use Symfony's composer dump-env to generate .env.local.php. ```bash composer dump-env prod ``` -------------------------------- ### Param Attribute Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Demonstrates using the #[Param] attribute to inject scalar values from environment variables, with automatic type casting. ```php use AsceticSoft\Wirebox\Attribute\Param; class DatabaseService { public function __construct( #[Param('DB_HOST')] private string $host, #[Param('DB_PORT')] private int $port, #[Param('APP_DEBUG')] private bool $debug = false, ) { } } ``` -------------------------------- ### Directory Scanning Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Scan directories to auto-register all concrete classes. ```php $builder->scan(__DIR__ . '/src'); $builder->scan(__DIR__ . '/modules'); ``` -------------------------------- ### Factory Registration Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Register a service with a custom factory closure. ```php $builder->register(Connection::class, function (Container $c) { return new Connection( host: $c->getParameter('db.host'), port: $c->getParameter('db.port'), ); }); ``` -------------------------------- ### Interface Binding Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Bind an interface to a concrete implementation. ```php $builder->bind(LoggerInterface::class, FileLogger::class); ``` -------------------------------- ### PSR-11 Container API Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Basic usage of the PSR-11 compliant methods for retrieving and checking service existence. ```php $service = $container->get(UserService::class); $exists = $container->has(UserService::class); ``` -------------------------------- ### Fluent Definition API Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Override or configure individual service definitions. ```php $builder->register(FileLogger::class) ->transient() // New instance every time ->lazy() // Deferred instantiation ->tag('logger') // Add a tag ->call('setFormatter', [JsonFormatter::class]); // Setter injection ``` -------------------------------- ### Exclude Attribute Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Shows how to use the #[Exclude] attribute to prevent a class from being auto-registered during directory scanning. ```php use AsceticSoft\Wirebox\Attribute\Exclude; #[Exclude] class InternalHelper { } ``` -------------------------------- ### #[Tag] Attribute Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Tag a class for grouped retrieval. Repeatable. ```php use AsceticSoft\Wirebox\Attribute\Tag; #[Tag('event.listener')] #[Tag('audit')] class UserCreatedListener { } ``` -------------------------------- ### #[Eager] Attribute Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Opt out of lazy instantiation when the container's default lazy mode is enabled. ```php use AsceticSoft\Wirebox\Attribute\Eager; #[Eager] class AppConfig { // Always created immediately, even when defaultLazy is on } ``` -------------------------------- ### #[Lazy] Attribute Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Return a lightweight proxy immediately; the real instance is created only when a property or method is first accessed. Uses PHP 8.4 native lazy objects (ReflectionClass::newLazyProxy). ```php use AsceticSoft\Wirebox\Attribute\Lazy; #[Lazy] class HeavyReportGenerator { public function __construct( private Connection $db, private CacheInterface $cache, ) { // expensive setup... } } ``` -------------------------------- ### Excluding Classes with Attribute Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Classes marked with #[Exclude] are skipped automatically during registration. ```php use AsceticSoft\Wirebox\Attribute\Exclude; #[Exclude] class InternalHelper { // Will not be registered in the container } ``` -------------------------------- ### Default Lazy Mode Configuration Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md ContainerBuilder enables lazy mode by default. You can disable this. ```php $builder->defaultLazy(false); ``` -------------------------------- ### Resolving Ambiguous Interface Binding Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md When multiple implementations of an interface are found, explicitly bind one to resolve ambiguity. ```php $builder->scan(__DIR__ . '/Services'); // PaymentInterface has StripePayment and PayPalPayment — ambiguous! $builder->bind(PaymentInterface::class, StripePayment::class); ``` -------------------------------- ### Excluding Files from Scanning Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Exclude files by glob pattern during directory scanning. ```php $builder->exclude('Entity/*'); $builder->exclude('*Test.php'); $builder->scan(__DIR__ . '/src'); ``` -------------------------------- ### Excluding Multiple Interfaces from Auto-Binding Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Exclude multiple interfaces from the auto-binding check simultaneously. ```php $builder->excludeFromAutoBinding( PaymentInterface::class, NotificationChannelInterface::class, ); ``` -------------------------------- ### Parameters with Embedded Env Expressions Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Parameters can also contain env expressions embedded in a larger string. ```php $builder->parameter('dsn', 'mysql:host=%env(DB_HOST)%;port=%env(DB_PORT)%'); ``` -------------------------------- ### Excluding Interface from Auto-Binding Source: https://github.com/ascetic-soft/wirebox/blob/main/README.md Suppress ambiguity errors for an interface without explicit binding. ```php $builder->excludeFromAutoBinding(PaymentInterface::class); $builder->scan(__DIR__ . '/Services'); // No error — PaymentInterface is excluded from the auto-binding check $container = $builder->build(); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.