Symfony bridge for SolidFrame architectural packages.
Bundle, compiler passes, console generators, DBAL stores, and modular monolith support — all wired into Symfony.
composer require solidframe/symfonyRegister the bundle:
// config/bundles.php
return [
// ...
SolidFrame\Symfony\SolidFrameBundle::class => ['all' => true],
];| Feature | What You Get |
|---|---|
| CQRS | CommandBus, QueryBus, handler auto-discovery via compiler pass |
| Event-Driven | EventBus, listener auto-discovery, multi-listener |
| Event Sourcing | DBAL EventStore, SnapshotStore, schema SQL |
| Saga | DBAL SagaStore, solidframe:saga:status |
| Modular | Module auto-discovery, registry, solidframe:module:list |
| Generators | 10 make:* commands for DDD, CQRS, events, sagas, modules |
SolidFrame discovers your handlers at compile time via HandlerDiscoveryCompilerPass.
// src/Application/Handler/PlaceOrderHandler.php
final readonly class PlaceOrderHandler implements CommandHandler
{
public function __invoke(PlaceOrder $command): void { /* ... */ }
}
// No service tags needed. Inject and use:
$commandBus->dispatch(new PlaceOrder('order-123', 'customer-456'));Handlers are discovered by marker interfaces (CommandHandler, QueryHandler, EventListener) and their __invoke() type hints.
# config/packages/solid_frame.yaml
solid_frame:
discovery:
enabled: true
paths: ['src']
cqrs:
command_bus:
middleware: []
query_bus:
middleware: []
event_driven:
event_bus:
middleware: []
event_sourcing:
event_store:
driver: dbal # 'dbal' or 'in_memory'
connection: null # null = default DBAL connection
table: event_store
snapshot_store:
driver: dbal
connection: null
table: snapshots
saga:
store:
driver: dbal
connection: null
table: sagas
modular:
path: modules
auto_discovery: true# DDD
php bin/console make:entity Order
php bin/console make:value-object Email
php bin/console make:aggregate-root Order
# CQRS
php bin/console make:cqrs-command PlaceOrder --handler
php bin/console make:command-handler PlaceOrderHandler --command-class=PlaceOrder
php bin/console make:query GetOrderById --handler
php bin/console make:query-handler GetOrderByIdHandler --query-class=GetOrderById
# Event-Driven
php bin/console make:domain-event OrderPlaced --listener
php bin/console make:event-listener SendOrderConfirmation --event-class=OrderPlaced
# Saga
php bin/console make:saga PlaceOrderSaga
# Module
php bin/console make:module OrderAll generators support subdirectories: php bin/console make:entity Order/OrderItem
# List registered modules
php bin/console solidframe:module:list
# View saga details
php bin/console solidframe:saga:status {saga-id}SQL schema files for DBAL stores are included in the package. Create the tables manually or via your migration system:
Event Store (event_store):
aggregate_id,version,event_type,payload(JSON),occurred_at- Unique constraint on
(aggregate_id, version)for optimistic concurrency
Snapshots (snapshots):
aggregate_id,aggregate_type,version,state(JSON)
Sagas (sagas):
id,saga_type,status,associations(JSON),state(serialized)
php bin/console make:module Inventoryuse SolidFrame\Modular\Module\AbstractModule;
final class InventoryModule extends AbstractModule
{
public function __construct()
{
parent::__construct(
name: 'inventory',
dependsOn: ['catalog'],
);
}
}When solid_frame.modular.auto_discovery is true, modules are discovered from *Module.php files in the configured path and registered automatically.
php bin/console solidframe:module:listAdd middleware to buses via config:
solid_frame:
cqrs:
command_bus:
middleware:
- App\Middleware\TransactionMiddleware
- App\Middleware\LoggingMiddlewareMiddleware classes are resolved from the service container.
The bundle registers these services:
| Interface | Implementation |
|---|---|
CommandBusInterface |
CommandBus with discovered handlers |
QueryBusInterface |
QueryBus with discovered handlers |
EventBusInterface |
EventBus with discovered listeners |
EventStoreInterface |
DbalEventStore or InMemoryEventStore |
SnapshotStoreInterface |
DbalSnapshotStore or InMemorySnapshotStore |
SagaStoreInterface |
DbalSagaStore or InMemorySagaStore |
ModuleRegistryInterface |
InMemoryModuleRegistry |
All services are public for container access. Store driver falls back to in-memory when DBAL is not installed.
- PHP 8.2+
- Symfony 6.4 or 7.x
Optional packages (installed as needed):
solidframe/ddd— formake:entity,make:value-object,make:aggregate-rootsolidframe/cqrs— for CommandBus, QueryBus, handler discoverysolidframe/event-driven— for EventBus, listener discoverysolidframe/event-sourcing— for EventStore, SnapshotStoresolidframe/modular— for module supportsolidframe/saga— for SagaStoredoctrine/dbal— for database-backed stores
- solidframe/core — Bus interfaces, Middleware
- solidframe/ddd — Entity, ValueObject, AggregateRoot
- solidframe/cqrs — CommandBus, QueryBus
- solidframe/event-driven — EventBus, Listeners
- solidframe/event-sourcing — EventStore, Snapshots
- solidframe/modular — Module contracts
- solidframe/saga — Saga lifecycle
- solidframe/laravel — Laravel alternative
This repository is a read-only split of the solidframe/solidframe monorepo, auto-synced on every push to main. Issues, pull requests, and discussions belong in the monorepo.