PHP code example of ascetic-soft / wirebox

1. Go to this page and download the library: Download ascetic-soft/wirebox library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

ascetic-soft / wirebox example snippets


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);

$builder = new ContainerBuilder(projectDir: __DIR__);

$builder->scan(__DIR__ . '/src');
$builder->scan(__DIR__ . '/modules');

$builder->exclude('Entity/*');
$builder->exclude('*Test.php');
$builder->scan(__DIR__ . '/src');

use AsceticSoft\Wirebox\Attribute\Exclude;

#[Exclude]
class InternalHelper
{
    // Will not be registered in the container
}

$builder->bind(LoggerInterface::class, FileLogger::class);

$builder->scan(__DIR__ . '/Services');
// PaymentInterface has StripePayment and PayPalPayment — ambiguous!
$builder->bind(PaymentInterface::class, StripePayment::class);

$builder->excludeFromAutoBinding(PaymentInterface::class);
$builder->scan(__DIR__ . '/Services');
// No error — PaymentInterface is excluded from the auto-binding check
$container = $builder->build();

$builder->excludeFromAutoBinding(
    PaymentInterface::class,
    NotificationChannelInterface::class,
);

$builder->register(Connection::class, function (Container $c) {
    return new Connection(
        host: $c->getParameter('db.host'),
        port: $c->getParameter('db.port'),
    );
});

$builder->register(FileLogger::class)
    ->transient()                                   // New instance every time
    ->lazy()                                        // Deferred instantiation
    ->tag('logger')                                 // Add a tag
    ->call('setFormatter', [JsonFormatter::class]);  // Setter injection

$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)%');

$builder->parameter('dsn', 'mysql:host=%env(DB_HOST)%;port=%env(DB_PORT)%');

use AsceticSoft\Wirebox\Attribute\Singleton;

#[Singleton]
class DatabaseConnection
{
}

use AsceticSoft\Wirebox\Attribute\Transient;

#[Transient]
class RequestContext
{
}

use AsceticSoft\Wirebox\Attribute\Lazy;

#[Lazy]
class HeavyReportGenerator
{
    public function __construct(
        private Connection $db,
        private CacheInterface $cache,
    ) {
        // expensive setup...
    }
}

$builder->register(HeavyReportGenerator::class)->lazy();

$builder->defaultLazy(false);

use AsceticSoft\Wirebox\Attribute\Eager;

#[Eager]
class AppConfig
{
    // Always created immediately, even when defaultLazy is on
}

$builder->register(AppConfig::class)->eager();

use AsceticSoft\Wirebox\Attribute\Tag;

#[Tag('event.listener')]
#[Tag('audit')]
class UserCreatedListener
{
}

foreach ($container->getTagged('event.listener') as $listener) {
    $listener->handle($event);
}

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
    {
        // ...
    }
}

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 { /* ... */ }
}

#[AutoconfigureTag('command.handler')]
#[AutoconfigureTag('auditable')]
interface CommandHandlerInterface {}

$builder->registerForAutoconfiguration(EventListenerInterface::class)
    ->tag('event.listener')
    ->singleton()
    ->lazy();

$builder->registerForAutoconfiguration(AsScheduled::class)
    ->tag('scheduler.task')
    ->transient();

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 { /* ... */ }
}

$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
}

use AsceticSoft\Wirebox\Attribute\Inject;

class NotificationService
{
    public function __construct(
        #[Inject(SmtpMailer::class)]
        private MailerInterface $mailer,
    ) {
    }
}

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,
    ) {
    }
}

use AsceticSoft\Wirebox\Attribute\Exclude;

#[Exclude]
class InternalHelper
{
}

$service = $container->get(UserService::class);
$exists  = $container->has(UserService::class);

$loggers = $container->getTagged('logger'); // iterable<object>

$host = $container->getParameter('db.host');
$all  = $container->getParameters();

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
    ) {
    }
}

$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',
);



$container = new App\Cache\CompiledContainer();
$service = $container->get(UserService::class);

// 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

use AsceticSoft\Wirebox\Exception\CircularDependencyException;

try {
    $builder->build();
} catch (CircularDependencyException $e) {
    // "Circular dependency detected: ServiceA -> ServiceB -> ServiceA. ..."
    echo $e->getMessage();
}

// 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();