Examples
use WPZylos\Framework\Container\Container;
$container = new Container();
// Core services
$container->singleton('config', fn() => new ConfigRepository());
$container->singleton('db', fn() => new DatabaseConnection());
// Repositories (depend on db)
$container->bind(UserRepository::class, fn($c) =>
new UserRepository($c->get('db'))
);
// Services (depend on repositories)
$container->bind(UserService::class, fn($c) =>
new UserService(
$c->get(UserRepository::class),
$c->get('config')
)
);
class DatabaseServiceProvider
{
public function register(Container $container): void
{
$container->singleton(DatabaseConnection::class, function ($c) {
$config = $c->get('config');
return new DatabaseConnection(
$config->get('database.host'),
$config->get('database.name')
);
});
$container->alias('db', DatabaseConnection::class);
}
}
// Usage
$provider = new DatabaseServiceProvider();
$provider->register($container);
// Bind interface to implementation
$container->bind(
PaymentGatewayInterface::class,
StripePaymentGateway::class
);
// Controllers depend on interface
class CheckoutController
{
public function __construct(
private PaymentGatewayInterface $gateway
) {}
}
// Stripe gateway injected automatically
$controller = $container->get(CheckoutController::class);
// Different implementations for different consumers
$container->bind(CacheInterface::class, function ($c) {
// Could base on context
if (defined('REDIS_HOST')) {
return new RedisCache(REDIS_HOST);
}
return new FileCache('/tmp/cache');
});
// Register event handlers
$container->bind(UserCreatedHandler::class)->addTag('event.handler');
$container->bind(WelcomeEmailHandler::class)->addTag('event.handler');
$container->bind(AuditLogHandler::class)->addTag('event.handler');
// Dispatcher collects all handlers
class EventDispatcher
{
public function __construct(private Container $container) {}
public function dispatch(Event $event): void
{
$handlers = $this->container->tagged('event.handler');
foreach ($handlers as $handler) {
$handler->handle($event);
}
}
}
class UserServiceTest extends TestCase
{
public function testCreateUser(): void
{
$container = new Container();
// Bind mock
$mockRepo = $this->createMock(UserRepository::class);
$mockRepo->expects($this->once())
->method('save');
$container->singleton(UserRepository::class, fn() => $mockRepo);
$service = $container->get(UserService::class);
$service->create(['name' => 'John']);
}
}