| name | acc-create-di-container |
| description | Generates DI Container configuration for PHP 8.5. 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.5 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 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;
final readonly class {Context}Module
{
public function getDefinitions(): array
{
return [
OrderRepository::class => [
'class' => DoctrineOrderRepository::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');
->();
->();
->();
}
{
->(
::,
::,
);
}
{
->(::)
->();
->(::)
->();
}
{
->(
::,
::,
);
}
{
;
}
}
Template: Symfony YAML Configuration
services:
_defaults:
autowire: true
autoconfigure: true
public: false
App\{Context}\Domain\Repository\OrderRepository:
class: App\{Context}\Infrastructure\Persistence\DoctrineOrderRepository
App\{Context}\Application\Command\:
resource: '../../../src/{Context}/Application/Command/*Handler.php'
tags:
- { name: messenger.message_handler }
App\{Context}\Application\Query\:
resource: '../../../src/{Context}/Application/Query/*Handler.php'
tags:
- { name: messenger.message_handler }
App\{Context}\Domain\Service\:
resource: '../../../src/{Context}/Domain/Service/*.php'
App\{Context}\Infrastructure\Adapter\PaymentGateway\:
resource: '../../../src/{Context}/Infrastructure/Adapter/PaymentGateway/*.php'
tags:
- { name: app.payment_gateway }
App\{Context}\Infrastructure\PaymentGatewayRegistry:
arguments:
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
{
public array $bindings = [
OrderRepository::class => DoctrineOrderRepository::class,
PaymentGateway::class => StripePaymentGateway::class,
];
public array = [
::,
::,
];
{
->();
->();
->();
}
{
->();
}
{
->app->(
::,
::,
);
}
{
->app->(::, function () {
(
->(::),
->(::),
);
});
}
{
->app->(::)
->(::)
->(function () {
= (, );
() {
=> ->(::),
=> ->(::),
=> (),
};
});
}
{
->app->([
::,
::,
], );
->app->(::, function () {
(
->(),
);
});
}
}
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;
}
$definition = $container->findDefinition(PaymentGatewayRegistry::class);
$taggedServices = $container->findTaggedServiceIds();
= [];
( => ) {
[] = ();
}
->(, );
}
}
Template: PHP-DI Configuration
<?php
declare(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 bindings
OrderRepository::class => \DI\autowire(DoctrineOrderRepository::class),
PaymentGateway::class => \DI\autowire(StripePaymentGateway::class),
// Factory-based creation
OrderFactory::class => \DI\factory(function ($container) {
return new OrderFactory(
$container->get(IdGenerator::class),
$container->get(::),
);
}),
:: => \DI\(function (, ) {
(
,
->(::),
);
}),
=> \DI\(function () {
[
->(::),
->(::),
];
}),
]);
};
Unit Test Template
<?php
declare(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;
{
->module = {Context}();
}
{
= ->module->();
->(::, );
->(::, [::]);
}
{
= ->module->();
->(, );
->([]);
}
{
= ->module->();
->(::, );
->(, [::]);
}
}
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 templates
examples.md - Real-world examples