Skip to content

Domain events

Martin Havlišta edited this page Aug 28, 2018 · 44 revisions

Work in progress

When executing a domain behaviour on an aggregate root domain entity inside a database transaction, it is always a good idea to keep the transaction small and short. Some processing does not have to be necessarily part of the transaction, and can be done later (e.g. audit, sending email, subsequent domain processing, etc). CoreDdd supports domain events to defer some processing to a later time. The domain event is raised from a domain method on a domain entity, and announces that some domain activity has happened. CoreDdd supports two ways of domain event handling:

  • handling the domain events within the transaction
  • handling the domain events after the transaction

Handling the domain events within the transaction

The domain events handlers are executed immediately when the domain event is raised. The domain event handler should not do much - for instance it should not do any database activity or any long processing, as it is running as a part of the database transaction. Ideally the domain event handler should just publish a message over a message bus notifying that something has happened, and subscribers of the messages will handle the message possibly in a different process or machine. Some message bus libraries like Rebus or NServiceBus allows to enlist the message publishing into an ambient transaction (TransactionScope), and the messages will not be published in the case the database transaction failure.

Example of raising ShipCargoPolicyItemAddedDomainEvent:

    public class Policy : Entity, IAggregateRoot
    {
        ...
        public virtual void AddShipCargoPolicyItem(ShipCargoPolicyItemArgs args)
        {
            var shipCargoPolicyItem = new ShipCargoPolicyItem(args);
            _items.Add(shipCargoPolicyItem);

            DomainEvents.RaiseEvent(new ShipCargoPolicyItemAddedDomainEvent
            {
                PolicyId = Id,
                ShipId = args.Ship.Id
            });
        }
        ...
    }

Clone this wiki locally