componenta/cqrs-app
Composer 安装命令:
composer require componenta/cqrs-app
包简介
Componenta application integration for CQRS discovery compilation
README 文档
README
componenta/cqrs-app connects componenta/cqrs to a Componenta application. It adds attribute discovery, class-finder compilers, command metadata compilation service, and the console worker command.
It does not contain domain commands, queries, middleware, transports, or CommandWorker. Those belong to componenta/cqrs.
Installation
composer require componenta/cqrs-app
Dependencies
| Dependency | Purpose |
|---|---|
PHP ^8.4 |
Modern syntax and strict types. |
componenta/cqrs |
Runtime commands, queries, middleware, transports, and worker. |
componenta/class-finder |
Class discovery and listener compiler support. |
componenta/tokenizer |
Class parsing during discovery. |
componenta/config |
Service registration and compile keys. |
componenta/arrayable |
Converting locators to arrays before cache write. |
psr/container |
Service lookup. |
psr/log |
Worker command logging. |
symfony/console |
cqrs:worker command. |
Setup
Register the provider after the runtime provider:
return [ new Componenta\CQRS\ConfigProvider(), new Componenta\CQRS\App\ConfigProvider(), ];
componenta/cqrs-app does not replace componenta/cqrs. The app package adds integration; the runtime package executes commands and queries.
Registered Services
| Section | Services |
|---|---|
invokables |
CommandAttributeMapContributor, CommandAttributeMapCompiler, QueryHandlerMapCompiler, CommandHandlerMapCompiler, CommandListenersMapCompiler. |
autowires |
WorkerCommand. |
factories |
AttributeCommandHandlerLocator, AttributeCommandListenersLocator, AttributeQueryHandlerLocator, plus runtime locator factories for QueryHandlerLocatorInterface, CommandHandlerLocatorInterface, and CommandListenersLocatorInterface. |
ClassFinderConfigKey::LISTENERS |
AttributeQueryHandlerLocator, AttributeCommandHandlerLocator, AttributeCommandListenersLocator. |
CompileConfigKey::LISTENER_COMPILERS |
QueryHandlerMapCompiler, CommandHandlerMapCompiler, CommandListenersMapCompiler. |
AppConfigKey::COMPILE_CACHE_CONTRIBUTORS |
CommandAttributeMapContributor. |
Runtime locator factories are registered in every environment. They read Componenta\Config\Config: in APP_ENV=development they combine the plain runtime locators from componenta/cqrs with finalized attribute locators, and outside development they return plain runtime locators backed by compiled maps.
Handler Discovery
Commands:
use Componenta\CQRS\Command\Attribute\AsCommandHandler; #[AsCommandHandler] final readonly class PublishPostHandler { public function __invoke(PublishPostCommand $command): void { // ... } }
If #[AsCommandHandler] does not specify a command, AttributeCommandHandlerLocator infers it from the handler parameter. It can also be explicit:
#[AsCommandHandler(PublishPostCommand::class)] final readonly class PublishPostHandler { public function __invoke(PublishPostCommand $command): void {} }
Queries:
use Componenta\CQRS\Query\Attribute\AsQueryHandler; #[AsQueryHandler] final readonly class GetPostHandler { public function __invoke(GetPostQuery $query): PostView { // ... } }
Command Listeners
#[AsCommandListener] registers a command event listener:
use Componenta\CQRS\Command\Attribute\AsCommandListener; use Componenta\CQRS\Command\Event\CommandProcessedEvent; #[AsCommandListener( command: PublishPostCommand::class, priority: 100, eventTypes: [CommandProcessedEvent::class], )] final readonly class NotifySubscribersListener { public function __invoke(CommandProcessedEvent $event): void { // ... } }
Listeners are sorted by priority. The listener map is compiled into ConfigKey::COMMAND_LISTENER_MAP.
Map Compilation
ConfigProvider contributes three class-finder listener compilers:
| Compiler | Config output |
|---|---|
QueryHandlerMapCompiler |
Componenta\CQRS\ConfigKey::QUERY_HANDLER_MAP |
CommandHandlerMapCompiler |
Componenta\CQRS\ConfigKey::COMMAND_HANDLER_MAP |
CommandListenersMapCompiler |
Componenta\CQRS\ConfigKey::COMMAND_LISTENER_MAP |
They receive finalized discovery locators and turn them into plain arrays. In production, the runtime package consumes those arrays without scanning files again.
Command Metadata
CommandAttributeMapCompiler compiles metadata for:
#[Async]#[Retry]#[Lock]
Output shape:
[
'known' => [
SendWelcomeEmailCommand::class => true,
],
'attributes' => [
SendWelcomeEmailCommand::class => [
'async' => [
'transport' => 'emails',
'delay' => 60,
],
],
],
]
Write that map to Componenta\CQRS\ConfigKey::COMMAND_ATTRIBUTE_MAP. Then componenta/cqrs creates CompiledCommandAttributeProvider. If the map is absent or Componenta\CQRS\ConfigKey::COMPILED_MAPS is disabled, the runtime falls back to ReflectionCommandAttributeProvider.
CommandAttributeMapCompiler is registered as a service, but it is not a class-finder listener compiler by itself. CommandAttributeMapContributor is registered in AppConfigKey::COMPILE_CACHE_CONTRIBUTORS; the application compile-cache step can pass discovered classes to it and receive the ConfigKey::COMMAND_ATTRIBUTE_MAP fragment.
Development Mode
With APP_ENV=development, the package registers attribute locators, contributes them to ClassFinderConfigKey::LISTENERS, and runtime factories return collectors. Each collector checks the finalized attribute locator first and falls back to the plain locator from componenta/cqrs. This lets the application work from attributes without manually writing handler maps.
This is convenient locally. Production should prefer compiled maps so file scanning and attribute parsing stay outside the hot path.
Production
The provider registers the same runtime locator factories in every environment. Those factories read Componenta\Config\Config: in development they wrap the plain runtime locators with attribute collectors, and outside development they return the plain runtime locators backed by compiled maps. Attribute locator services are still registered because listener restoration and compilation can need them:
ConfigKey::COMMAND_HANDLER_MAPConfigKey::COMMAND_LISTENER_MAPConfigKey::QUERY_HANDLER_MAP- optionally
ConfigKey::COMMAND_ATTRIBUTE_MAP
Worker Command
WorkerCommand is registered as an autowired service. The command name is cqrs:worker.
php bin/console cqrs:worker php bin/console cqrs:worker emails --sleep=5 --limit=100 php bin/console cqrs:worker emails --time-limit=3600 --memory-limit=128
Options:
| Option | Meaning |
|---|---|
transport |
Transport name. Defaults to default. |
--sleep |
Seconds to wait when the queue is empty. |
--limit |
Maximum processed commands. |
--time-limit |
Maximum runtime in seconds. |
--memory-limit |
Maximum memory in megabytes. |
The command needs CommandBusInterface, CommandSerializerInterface, and TransportRegistryInterface. The application must configure those services.
Boundaries
Use componenta/cqrs-app when an application needs:
- discovery for
#[AsCommandHandler],#[AsQueryHandler], and#[AsCommandListener]; - handler and listener map compilation;
- command metadata compilation service;
cqrs:workerconsole command.
Libraries that only dispatch commands or handle queries should depend on componenta/cqrs, not componenta/cqrs-app.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-17