Domain Library.

Provides a set of components and abstractions to help implement domain driven object model with CQRS.

Article image for: Domain Library


Aggregate Root
Domain Events
Value Objects
Doctrine Mappings
Doctrine Enumeration Bridge
Symfony Messenger


Somnambulist Domain Package

GitHub Actions Build Status

Provides a core set of support classes for building domain oriented projects. This library compiles the previously separate domain and mapping libraries into a single project for easier maintenance.

It consists of:

  • Commands
    • CommandBus interface / abstract command
    • SF Messenger implementation
  • Doctrine
    • Enumeration factories + Type bindings
    • Additional types / type overrides for the Doctrine Type system
    • Abstract EntityLocator that extends EntityRepository
    • Custom Postgres DQL functions
    • Custom traits for EntityRepository
  • Entities
    • Contracts - value object interface definitions
    • Types - a collection of value-objects, enumerations and an aggregate root
    • AggregateRoot - an aggregate root stub implementation that can raise events
    • AbstractEntity and AbstractEntityCollection - child entities and helper for an aggregate root
  • Events
    • EventBus interface / abstract event
    • SF Messenger EventBus implementation
    • Doctrine subscriber that broadcasts onFlush all events from aggregate roots
    • Custom serializer to handle encode/decode when the event class does not exist
  • Jobs
    • JobQueue interface / abstract job
    • SF Messenger implementation
  • Queries
    • QueryBus interface / abstract query
    • SF Messenger implementation
  • default XML mappings for embeddable objects in Doctrine .dcm.xml and Symfony .orm.xml conventions


  • PHP 8.0+
  • mb_string
  • bcmath
  • beberlei/assert
  • eloquent/enumeration
  • somnambulist/collection
  • symfony/messenger for the Messenger bus implementations.


Install using composer, or checkout / pull the files from

  • composer require somnambulist/domain


To get the most from this library, it is strongly advisable to read about Domain Driven Design and in particular how DDD can influence and help you model the business problem you are trying to solve. Without a clear understanding of your businesses domain and the problems that are being faced, it can be difficult to implement the logic.

With that said, there are several key things to bare in mind:

  • try to keep a single aggregate root per context
  • do not directly link aggregate roots - only use the identity
  • do not cross-reference entities from other contexts
  • keep reads and writes as distinctly separate tasks
  • name your objects, events, commands, queries etc. for actual things in your business
  • avoid magic as much as possible - especially Doctrine lifecycle event subscribers.