<< All versions
Skill v1.0.1
currentAutomated scan100/100dykyi-roman/awesome-claude-code/create-di-container
4 files
──Details
PublishedJune 8, 2026 at 01:15 PM
Content Hashsha256:842892f5418c96b3...
Git SHA2897d0739800
Bump Typepatch
──Files
Files (1 file, 13.6 KB)
SKILL.md13.6 KBactive
SKILL.md · 483 lines · 13.6 KB
version: "1.0.1" name: create-di-container description: Generates DI Container configuration for PHP 8.4. Creates module classes, service providers, container configuration, and autowiring setup. Supports Symfony, Laravel, and PHP-DI patterns. Includes unit tests.
DI Container Generator
Overview
Generates Dependency Injection container configuration components for PHP 8.4 following DDD and Clean Architecture principles.
When to Use
- Setting up new bounded context DI configuration
- Creating service provider/module for feature
- Configuring autowiring and interface bindings
- Registering tagged services (handlers, strategies)
- Setting up factory-based service creation
Generated Components
| Component | Location | Purpose | |
|---|---|---|---|
| Module | src/Infrastructure/DependencyInjection/{Context}Module.php | Service registration | |
| ServiceProvider | src/Infrastructure/DependencyInjection/{Context}ServiceProvider.php | Laravel-style provider | |
| Extension | src/Infrastructure/DependencyInjection/{Context}Extension.php | Symfony bundle extension | |
| Configuration | config/services/{context}.yaml | YAML configuration | |
| CompilerPass | src/Infrastructure/DependencyInjection/Compiler/{Name}Pass.php | Service manipulation |
Input Requirements
- Context name - Bounded context (e.g., "Order", "Payment")
- Framework - Symfony, Laravel, or PHP-DI
- Services to register - Interfaces and implementations
- Tagged services - Handlers, strategies, listeners
File Placement
src/└── Infrastructure/└── DependencyInjection/├── {Context}Module.php # Pure PHP registration├── {Context}ServiceProvider.php # Laravel├── {Context}Extension.php # Symfony└── Compiler/└── {Handler}Pass.php # Compiler passesconfig/└── services/└── {context}.yaml # YAML config
Template: Module Class (Framework-agnostic)
php
<?phpdeclare(strict_types=1);namespace App\{Context}\Infrastructure\DependencyInjection;use App\{Context}\Application\Command\CreateOrderHandler;use App\{Context}\Application\Query\GetOrderHandler;use App\{Context}\Domain\Repository\OrderRepository;use App\{Context}\Infrastructure\Persistence\DoctrineOrderRepository;/*** Dependency injection module for {Context} bounded context.*/final readonly class {Context}Module{/*** @return array<string, array{class: class-string, arguments: array<string>}>*/public function getDefinitions(): array{return [// Repository bindingsOrderRepository::class => ['class' => DoctrineOrderRepository::class,'arguments' => ['@doctrine.entity_manager'],],// Command handlersCreateOrderHandler::class => ['class' => CreateOrderHandler::class,'arguments' => ['@' . OrderRepository::class,'@event_dispatcher',],'tags' => ['command_handler'],],// Query handlersGetOrderHandler::class => ['class' => GetOrderHandler::class,'arguments' => ['@order_read_repository'],'tags' => ['query_handler'],],];}/*** @return array<string, class-string>*/public function getInterfaceBindings(): array{return [OrderRepository::class => DoctrineOrderRepository::class,PaymentGateway::class => StripePaymentGateway::class,];}/*** @return array<string, array<class-string>>*/public function getTaggedServices(): array{return ['command_handler' => [CreateOrderHandler::class,CancelOrderHandler::class,ShipOrderHandler::class,],'query_handler' => [GetOrderHandler::class,ListOrdersHandler::class,],'payment_gateway' => [StripePaymentGateway::class,PayPalPaymentGateway::class,],];}}
Template: Symfony Service Provider
php
<?phpdeclare(strict_types=1);namespace App\{Context}\Infrastructure\DependencyInjection;use Symfony\Component\DependencyInjection\ContainerBuilder;use Symfony\Component\DependencyInjection\Extension\Extension;use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;use Symfony\Component\Config\FileLocator;final class {Context}Extension extends Extension{public function load(array $configs, ContainerBuilder $container): void{$loader = new YamlFileLoader($container,new FileLocator(__DIR__ . '/../../config'),);$loader->load('services.yaml');$this->registerRepositories($container);$this->registerHandlers($container);$this->registerAdapters($container);}private function registerRepositories(ContainerBuilder $container): void{$container->setAlias(OrderRepository::class,DoctrineOrderRepository::class,);}private function registerHandlers(ContainerBuilder $container): void{$container->registerForAutoconfiguration(CommandHandler::class)->addTag('messenger.message_handler');$container->registerForAutoconfiguration(QueryHandler::class)->addTag('messenger.message_handler');}private function registerAdapters(ContainerBuilder $container): void{$container->setAlias(PaymentGateway::class,StripePaymentGateway::class,);}public function getAlias(): string{return '{context}';}}
Template: Symfony YAML Configuration
yaml
# config/services/{context}.yamlservices:_defaults:autowire: trueautoconfigure: truepublic: false# RepositoriesApp\{Context}\Domain\Repository\OrderRepository:class: App\{Context}\Infrastructure\Persistence\DoctrineOrderRepository# Command Handlers (auto-tagged by messenger)App\{Context}\Application\Command\:resource: '../../../src/{Context}/Application/Command/*Handler.php'tags:- { name: messenger.message_handler }# Query HandlersApp\{Context}\Application\Query\:resource: '../../../src/{Context}/Application/Query/*Handler.php'tags:- { name: messenger.message_handler }# Domain ServicesApp\{Context}\Domain\Service\:resource: '../../../src/{Context}/Domain/Service/*.php'# Adapters (Payment Gateways as tagged services)App\{Context}\Infrastructure\Adapter\PaymentGateway\:resource: '../../../src/{Context}/Infrastructure/Adapter/PaymentGateway/*.php'tags:- { name: app.payment_gateway }# Payment Gateway RegistryApp\{Context}\Infrastructure\PaymentGatewayRegistry:arguments:$gateways: !tagged_iterator app.payment_gateway
Template: Laravel Service Provider
php
<?phpdeclare(strict_types=1);namespace App\{Context}\Infrastructure\DependencyInjection;use App\{Context}\Application\Command\CreateOrderHandler;use App\{Context}\Domain\Repository\OrderRepository;use App\{Context}\Infrastructure\Persistence\DoctrineOrderRepository;use Illuminate\Support\ServiceProvider;final class {Context}ServiceProvider extends ServiceProvider{/*** @var array<class-string, class-string>*/public array $bindings = [OrderRepository::class => DoctrineOrderRepository::class,PaymentGateway::class => StripePaymentGateway::class,];/*** @var array<class-string>*/public array $singletons = [PaymentGatewayRegistry::class,OrderReadRepository::class,];public function register(): void{$this->registerRepositories();$this->registerHandlers();$this->registerAdapters();}public function boot(): void{$this->registerTaggedServices();}private function registerRepositories(): void{$this->app->bind(OrderRepository::class,DoctrineOrderRepository::class,);}private function registerHandlers(): void{$this->app->bind(CreateOrderHandler::class, function ($app) {return new CreateOrderHandler($app->make(OrderRepository::class),$app->make(EventDispatcher::class),);});}private function registerAdapters(): void{$this->app->when(PaymentService::class)->needs(PaymentGateway::class)->give(function ($app) {$gateway = config('payment.gateway', 'stripe');return match ($gateway) {'stripe' => $app->make(StripePaymentGateway::class),'paypal' => $app->make(PayPalPaymentGateway::class),default => throw new InvalidConfigurationException(),};});}private function registerTaggedServices(): void{$this->app->tag([StripePaymentGateway::class,PayPalPaymentGateway::class,], 'payment_gateways');$this->app->bind(PaymentGatewayRegistry::class, function ($app) {return new PaymentGatewayRegistry($app->tagged('payment_gateways'),);});}}
Template: Symfony Compiler Pass
php
<?phpdeclare(strict_types=1);namespace App\{Context}\Infrastructure\DependencyInjection\Compiler;use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;use Symfony\Component\DependencyInjection\ContainerBuilder;use Symfony\Component\DependencyInjection\Reference;final class PaymentGatewayPass implements CompilerPassInterface{public function process(ContainerBuilder $container): void{if (!$container->has(PaymentGatewayRegistry::class)) {return;}$definition = $container->findDefinition(PaymentGatewayRegistry::class);$taggedServices = $container->findTaggedServiceIds('app.payment_gateway');$gateways = [];foreach ($taggedServices as $id => $tags) {$gateways[] = new Reference($id);}$definition->setArgument('$gateways', $gateways);}}
Template: PHP-DI Configuration
php
<?phpdeclare(strict_types=1);use App\{Context}\Domain\Repository\OrderRepository;use App\{Context}\Infrastructure\Persistence\DoctrineOrderRepository;use DI\ContainerBuilder;return function (ContainerBuilder $containerBuilder): void {$containerBuilder->addDefinitions([// Interface bindingsOrderRepository::class => \DI\autowire(DoctrineOrderRepository::class),PaymentGateway::class => \DI\autowire(StripePaymentGateway::class),// Factory-based creationOrderFactory::class => \DI\factory(function ($container) {return new OrderFactory($container->get(IdGenerator::class),$container->get(Clock::class),);}),// Decorated serviceLoggingOrderRepository::class => \DI\decorate(function ($previous, $container) {return new LoggingOrderRepository($previous,$container->get(LoggerInterface::class),);}),// Tagged services collection'payment_gateways' => \DI\factory(function ($container) {return [$container->get(StripePaymentGateway::class),$container->get(PayPalPaymentGateway::class),];}),]);};
Unit Test Template
php
<?phpdeclare(strict_types=1);namespace Tests\{Context}\Infrastructure\DependencyInjection;use App\{Context}\Domain\Repository\OrderRepository;use App\{Context}\Infrastructure\DependencyInjection\{Context}Module;use App\{Context}\Infrastructure\Persistence\DoctrineOrderRepository;use PHPUnit\Framework\Attributes\CoversClass;use PHPUnit\Framework\Attributes\Group;use PHPUnit\Framework\TestCase;#[Group('unit')]#[CoversClass({Context}Module::class)]final class {Context}ModuleTest extends TestCase{private {Context}Module $module;protected function setUp(): void{$this->module = new {Context}Module();}public function testProvidesRepositoryBindings(): void{$bindings = $this->module->getInterfaceBindings();$this->assertArrayHasKey(OrderRepository::class, $bindings);$this->assertSame(DoctrineOrderRepository::class, $bindings[OrderRepository::class]);}public function testProvidesTaggedServices(): void{$tagged = $this->module->getTaggedServices();$this->assertArrayHasKey('command_handler', $tagged);$this->assertNotEmpty($tagged['command_handler']);}public function testProvidesServiceDefinitions(): void{$definitions = $this->module->getDefinitions();$this->assertArrayHasKey(CreateOrderHandler::class, $definitions);$this->assertArrayHasKey('arguments', $definitions[CreateOrderHandler::class]);}}
SOLID Compliance
| Principle | Implementation | |
|---|---|---|
| SRP | Module only handles DI registration | |
| OCP | Tagged services enable extension without modification | |
| DIP | Interface-to-implementation bindings | |
| ISP | Small focused modules per context |
References
See references/ for detailed documentation:
templates.md- Additional templatesexamples.md- Real-world examples