gilsegura/shared
Composer 安装命令:
composer require gilsegura/shared
包简介
Framework-agnostic DDD, Event Sourcing and CQRS building blocks: domain value objects, aggregates, event store, command/query buses, criteria DSL and read models.
README 文档
README
Framework-agnostic building blocks for DDD, CQRS and event sourcing. It provides
the domain primitives (value objects, events, aggregates), the command/query and
event bus contracts, the event store and upcasting contracts, a criteria DSL for
querying, and read-model projection support — all as plain PHP, with no
framework dependency. The gilsegura/shared-bundle package wires these onto
Symfony, Messenger and Doctrine.
Installation
composer require gilsegura/shared
Domain primitives
Shared\Domain holds the value objects and the event envelope every other piece
builds on:
Uuid,Email,HashedPassword,NotEmptyString,DateTimeImmutable— immutable value objects with validation and equality.DomainEventInterface— marker for domain events; events are serializable so they can be stored and replayed.DomainMessage— wraps a domain event (payload) together with the aggregateid,playhead,MetadataandrecordedAt. Thetypeis derived from the event class. This is the unit the event store persists and the buses carry.DomainEventStream— an ordered, iterable stream ofDomainMessages.Metadata— arbitrary key/value context attached to a message.
Command and query handling
Shared\CommandHandling defines the CQRS contracts, with no transport opinion:
CommandInterface/QueryInterface— markers for messages.CommandHandlerInterface/QueryHandlerInterface— markers for handlers, generic over the message they handle.CommandBusInterface/QueryBusInterface— the buses a use case depends on. An adapter (e.g. in the bundle) provides the concrete bus.
Event handling
Shared\EventHandling is the synchronous, in-process event bus:
EventListenerInterface— a listener invoked with aDomainMessage.EventBusInterface— publishes aDomainEventStreamto its listeners.SimpleEventBus— publishes to its listeners in order, fail-fast: the first listener that throws stops the dispatch.
Event sourcing
Shared\EventSourcing turns event streams into aggregates and back:
AbstractEventSourcedAggregateRoot— base aggregate.apply()records an event and routes it to anapplyXxxmethod resolved from the event's short name;uncommittedEvents()returns what to persist;initialize()rebuilds state from a stream. Child entities are reachable throughchildEntities().AbstractEventSourcedEntity— same apply mechanics for entities nested inside an aggregate.AbstractEventSourcingRepository— loads an aggregate from the event store (through a factory) and saves its uncommitted events, publishing them on the event bus.AggregateRootFactoryInterface+PublicConstructorAggregateRootFactory— rebuild an aggregate instance from a stream.EventStreamDecoratorInterface+MetadataEnricher— decorate the outgoing stream, e.g. to enrich every message's metadata.
Event store
Shared\EventStore is the persistence contract for streams:
EventStoreInterface—load/appendaDomainEventStreamby aggregate id, withStreamNotFoundException/StreamAlreadyExistsException.EventStoreManagerInterface— visiting/streaming events for replay and maintenance.EventVisitorInterface/CallableEventVisitor— visit matching events.
Upcasting
Shared\Upcasting keeps old event shapes loadable as the schema evolves:
UpcasterInterface— transforms aDomainMessageinto its newer shape, or returns it unchanged when the event is not its concern.SequentialUpcasterChain— runs the message through its upcasters in order, each receiving the output of the previous one. With no upcasters the message passes through unchanged.UpcastingEventStore— decorates an event store so events are upcast both when they are loaded (load) and when they are visited (visitEvents), so a rebuild sees the same current shapes a load produces. An empty chain is a transparent pass-through.
Criteria
Shared\Criteria is a small DSL for expressing filters and ordering in domain
terms, independent of any database:
- Composites
AndX/OrXcombine comparisons such asEqId,EqEmail,EqPlayhead,ByPlayhead,ByRecordedAt. OrderXexpresses sorting.- The
Exprnamespace is the lower-level expression tree the comparisons map to.
An infrastructure adapter translates these into a concrete query (the bundle, for example, converts them to Doctrine criteria).
Queries and read models
Shared\Query—QueryBuilderbuilds a typed query from criteria;CollectionQuery/SingleResultQueryexpress the expected result shape.Shared\ReadModel—ReadModelInterfaceandReadModelRepositoryInterfaceare the read-side contracts;AbstractProjectorimplementsEventListenerInterfaceand resolves anapplyXxxmethod from each event's short name, so a projector only writes handlers for the events it reacts to.
Replaying
Shared\Replaying\Replayer visits the events matching a criteria from the store
and feeds them to an event visitor — e.g. to rebuild a read model from history.
When the store is an UpcastingEventStore, the visited events are upcast too, so
a projector reacting to the replay sees the current event shapes.
Specifications
Shared\Specification\AbstractSpecification is the base for composable domain
specifications (business rules expressed as objects).
Exceptions
Shared\Exception provides a hierarchy mapping domain failures to intent —
NotFoundException, ConflictException, ForbiddenException,
UnauthorizedException, InvalidInputException, InfrastructureException,
UnexpectedException — so transport layers can translate them to the right
status without leaking domain details.
Support
Shared\Support\ClassName resolves the short name of a class, used to map events
to their applyXxx methods.
License
MIT. See LICENSE.
统计信息
- 总下载量: 330
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 5
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2024-04-15