agentskills.codes
CR

create-di-container

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.

Install

mkdir -p .claude/skills/create-di-container && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/16158" && unzip -o skill.zip -d .claude/skills/create-di-container && rm skill.zip

Installs to .claude/skills/create-di-container

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

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.
208 charsno explicit “when” trigger

About this skill

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

ComponentLocationPurpose
Modulesrc/Infrastructure/DependencyInjection/{Context}Module.phpService registration
ServiceProvidersrc/Infrastructure/DependencyInjection/{Context}ServiceProvider.phpLaravel-style provider
Extensionsrc/Infrastructure/DependencyInjection/{Context}Extension.phpSymfony bundle extension
Configurationconfig/services/{context}.yamlYAML configuration
CompilerPasssrc/Infrastructure/DependencyInjection/Compiler/{Name}Pass.phpService manipulation

Input Requirements

  1. Context name - Bounded context (e.g., "Order", "Payment")
  2. Framework - Symfony, Laravel, or PHP-DI
  3. Services to register - Interfaces and implementations
  4. 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 passes

config/
└── services/
    └── {context}.yaml                    # YAML config

Template: Module Class (Framework-agnostic)

<?php

declare(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 bindings
            OrderRepository::class => [
                'class' => DoctrineOrderRepository::class,
                'arguments' => ['@doctrine.entity_manager'],
            ],

            // Command handlers
            CreateOrderHandler::class => [
                'class' => CreateOrderHandler::class,
                'arguments' => [
                    '@' . OrderRepository::class,
                    '@event_dispatcher',
                ],
                'tags' => ['command_handler'],
            ],

            // Query handlers
            GetOrderHandler::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

declare(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

# config/services/{context}.yaml

services:
  _defaults:
    autowire: true
    autoconfigure: true
    public: false

  # Repositories
  App\{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 Handlers
  App\{Context}\Application\Query\:
    resource: '../../../src/{Context}/Application/Query/*Handler.php'
    tags:
      - { name: messenger.message_handler }

  # Domain Services
  App\{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 Registry
  App\{Context}\Infrastructure\PaymentGatewayRegistry:
    arguments:
      $gateways: !tagged_iterator app.payment_gateway

Template: Laravel Service Provider

<?php

declare(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

declare(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;
        }

        $defini

---

*Content truncated.*

Search skills

Search the agent skills registry