CR

create-di-container

Scaffold dependency injection configurations for PHP applications.

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
Intermediate

Key capabilities

  • Generate module classes for service registration
  • Create service providers for Laravel applications
  • Develop extension classes for Symfony bundles
  • Configure YAML files for container services
  • Generate unit tests for DI container components

How it works

The skill generates DI container configuration components for PHP 8.4 by taking context, framework, and service details as input. It produces module classes, service providers, extensions, and YAML configurations.

Inputs & outputs

You give it
Context name, framework, services to register, tagged services
You get back
PHP classes and YAML configuration for DI container

When to use create-di-container

  • Setup a new bounded context DI container
  • Create a feature service provider
  • Configure autowiring for interfaces
  • Register tagged services in symfony

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.*

When not to use it

  • When working with PHP versions older than 8.4
  • When not using Symfony, Laravel, or PHP-DI frameworks

Limitations

  • The skill generates DI Container configuration for PHP 8.4.
  • The skill supports Symfony, Laravel, or PHP-DI patterns.

How it compares

This skill automates the generation of DI container components for PHP frameworks, ensuring architecture compliance and reducing manual boilerplate code compared to writing these configurations by hand.

Compared to similar skills

create-di-container side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
create-di-container (this skill)06moNo flagsIntermediate
laravel-patterns04moReviewAdvanced
dto-contract01moNo flagsIntermediate
laravel-event-driven-architecture01moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry