承接 solidframe/cqrs 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

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

solidframe/cqrs

最新稳定版本:v0.1.0

Composer 安装命令:

composer require solidframe/cqrs

包简介

CQRS building blocks: Command, Query, Handlers, and Bus implementations for SolidFrame

README 文档

README

Command Query Responsibility Segregation: CommandBus, QueryBus, Handlers, and Middleware.

Commands produce side effects and return nothing. Queries return data and produce no side effects.

Installation

composer require solidframe/cqrs

Quick Start

Define a Command and Handler

use SolidFrame\Cqrs\Command;
use SolidFrame\Cqrs\CommandHandler;

final readonly class PlaceOrder implements Command
{
    public function __construct(
        public string $orderId,
        public string $customerId,
    ) {}
}

final readonly class PlaceOrderHandler implements CommandHandler
{
    public function __construct(private OrderRepository $orders) {}

    public function __invoke(PlaceOrder $command): void
    {
        $order = Order::place(
            new OrderId($command->orderId),
            new CustomerId($command->customerId),
        );

        $this->orders->save($order);
    }
}

Define a Query and Handler

use SolidFrame\Cqrs\Query;
use SolidFrame\Cqrs\QueryHandler;

final readonly class GetOrderById implements Query
{
    public function __construct(public string $orderId) {}
}

final readonly class GetOrderByIdHandler implements QueryHandler
{
    public function __construct(private OrderRepository $orders) {}

    public function __invoke(GetOrderById $query): ?OrderDto
    {
        $order = $this->orders->find(new OrderId($query->orderId));

        return $order ? OrderDto::fromEntity($order) : null;
    }
}

Dispatch

// Command — fire and forget
$commandBus->dispatch(new PlaceOrder(
    orderId: 'order-123',
    customerId: 'customer-456',
));

// Query — get result
$order = $queryBus->ask(new GetOrderById(orderId: 'order-123'));

Standalone Usage

Without a framework bridge, wire the bus manually:

use SolidFrame\Cqrs\Handler\InMemoryHandlerResolver;
use SolidFrame\Cqrs\Bus\CommandBus;
use SolidFrame\Cqrs\Bus\QueryBus;

$resolver = new InMemoryHandlerResolver();
$resolver->register(PlaceOrder::class, new PlaceOrderHandler($orders));

$commandBus = new CommandBus($resolver);
$commandBus->dispatch(new PlaceOrder('order-123', 'customer-456'));

Middleware

Add cross-cutting concerns to bus processing.

use SolidFrame\Core\Middleware\MiddlewareInterface;

final readonly class TransactionMiddleware implements MiddlewareInterface
{
    public function __construct(private Connection $connection) {}

    public function handle(object $message, callable $next): mixed
    {
        $this->connection->beginTransaction();

        try {
            $result = $next($message);
            $this->connection->commit();

            return $result;
        } catch (\Throwable $e) {
            $this->connection->rollBack();
            throw $e;
        }
    }
}

// With middleware
$commandBus = new CommandBus($resolver, [
    new TransactionMiddleware($connection),
    new LoggingMiddleware($logger),
]);

Middleware executes in registration order. Each middleware calls $next($message) to pass to the next one.

Handler Resolution

Handlers are resolved by the message type passed to __invoke(). The convention:

  • PlaceOrder command → PlaceOrderHandler::__invoke(PlaceOrder $command)
  • GetOrderById query → GetOrderByIdHandler::__invoke(GetOrderById $query)

One handler per command/query. Multiple handlers for the same message type will throw an exception.

API Reference

Class / Interface Purpose
Command Marker interface for commands
Query Marker interface for queries
CommandHandler Marker interface for command handlers
QueryHandler Marker interface for query handlers
CommandBus Dispatches commands through middleware to handlers
QueryBus Dispatches queries through middleware to handlers
MessageBus Abstract base for both buses
HandlerResolverInterface Contract for resolving handlers
InMemoryHandlerResolver In-memory handler registry
HandlerNotFoundException Thrown when no handler matches

Related Packages

Contributing

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.

统计信息

  • 总下载量: 6
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 7
  • 依赖项目数: 0
  • 推荐数: 2

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-04-18

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固