componenta/cqrs-app 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

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 in development AttributeCommandHandlerLocator, AttributeCommandListenersLocator, AttributeQueryHandlerLocator, QueryHandlerLocatorInterface.
aliases in development CommandHandlerLocatorInterface => AttributeCommandHandlerLocator, CommandListenersLocatorInterface => AttributeCommandListenersLocator.
CompileConfigKey::LISTENER_COMPILERS QueryHandlerMapCompiler, CommandHandlerMapCompiler, CommandListenersMapCompiler.
AppConfigKey::COMPILE_CACHE_CONTRIBUTORS CommandAttributeMapContributor.

Development factories and aliases are enabled only when APP_ENV=development. Production should read compiled maps from configuration.

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 CQRS_COMPILED_MAPS=false, 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. They let 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

In production, the provider does not register development factories and aliases for attribute locators. The application is expected to load compiled maps:

  • ConfigKey::COMMAND_HANDLER_MAP
  • ConfigKey::COMMAND_LISTENER_MAP
  • ConfigKey::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:worker console 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

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-14

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固