A PowerModuleSetup extension for the Power Modules Framework that automatically discovers and registers Symfony Console commands from your modules.
This plugin bridges Symfony Console with the Power Modules Framework's modular architecture. It allows modules to export console commands while maintaining the framework's encapsulation principles. Commands are auto-discovered, lazily loaded from the DI container, and registered into a central Console\Application.
- 🔍 Auto-Discovery: Automatically finds commands exported by modules via
#[AsCommand]attribute - ⚡ Lazy Loading: Commands are instantiated only when executed via
ContainerCommandLoader - 🔒 Encapsulation: Each module's commands remain isolated in their module's container scope
- 💉 DI Integration: Full dependency injection support for command constructors
- 📦 Zero Configuration: Just export your commands from modules - registration is automatic
composer require power-modules/console1. Create a command in your module:
<?php
namespace MyApp\Orders;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
#[AsCommand(name: 'orders:process', description: 'Process pending orders')]
final class ProcessOrdersCommand extends Command
{
public function __construct(
private readonly OrderService $orderService,
) {
parent::__construct();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->orderService->processPendingOrders();
$output->writeln('Orders processed successfully!');
return Command::SUCCESS;
}
}2. Export the command from your module:
<?php
namespace MyApp\Orders;
use Modular\Framework\PowerModule\Contract\ExportsComponents;
use Modular\Framework\PowerModule\Contract\PowerModule;
use Modular\Framework\PowerModule\Contract\ConfigurableContainerInterface;
final class OrderModule implements PowerModule, ExportsComponents
{
public static function exports(): array
{
return [
ProcessOrdersCommand::class, // Export your command
];
}
public function register(ConfigurableContainerInterface $container): void
{
$container->set(OrderService::class, OrderService::class); // Stays private to this module
$container->set(ProcessOrdersCommand::class, ProcessOrdersCommand::class)
->addArguments([OrderService::class]) // DI just works!
;
}
}3. Add the setup to your application:
# bin/console
<?php
declare(strict_types=1);
use Modular\Console\PowerModule\Setup\ConsoleCommandsSetup;
use Modular\Framework\App\ModularAppBuilder;
use Symfony\Component\Console\Application;
require __DIR__ . '/../vendor/autoload.php';
$app = new ModularAppBuilder(__DIR__)
->withModules(
\MyApp\Orders\OrderModule::class,
\MyApp\Users\UserModule::class,
)
->addPowerModuleSetup(new ConsoleCommandsSetup())
->build()
;
// Get the configured Console Application
$console = $app->get(Application::class);
$console->run();4. Run your commands:
php bin/console orders:process
php bin/console list # See all registered commandsThe plugin uses a two-phase setup process aligned with the framework's PowerModuleSetup lifecycle:
- PRE Phase: Scans all modules implementing
ExportsComponents, discovers classes extendingCommandwith#[AsCommand]attributes, and builds a command map - POST Phase: Creates a
ContainerCommandLoaderwith the collected commands and registers theConsole\Applicationin the root container
Commands are lazily loaded - they're instantiated from the container only when executed, ensuring efficient memory usage and fast startup.
- PHP: ^8.4
- power-modules/framework: ^2.1
- symfony/console: ^7.3
- Commands must extend
Symfony\Component\Console\Command\Command - Commands must be annotated with
#[AsCommand]attribute - Commands must be in the module's
exports()array - Dependencies are resolved via constructor injection from the module's container
- The
Console\Applicationinstance is registered in the root container for retrieval
Contributions are welcome! This project follows the same standards as the Power Modules Framework:
- PHPStan Level 8 - Very strict static analysis
- PHP CS Fixer - Code style consistency
- PHPUnit - Comprehensive test coverage
make test # Run tests
make phpstan # Static analysis
make codestyle # Code style checkMIT License. See LICENSE for details.
Part of the Power Modules Framework ecosystem - Building truly modular PHP applications with runtime-enforced encapsulation.