Persistence and Domain Events with persistence ignorant objects

后端 未结 2 1375
佛祖请我去吃肉
佛祖请我去吃肉 2021-02-03 13:01

I\'ve been studying on domain driven design in conjunction with domain events. I really like the separations of concerns those events provide. I ran into an issue with the order

相关标签:
2条回答
  • 2021-02-03 13:13

    Either your (transactional) event handlers enlist in the (potentially distributed) transaction, or you publish/handle the events after the transaction committed. Your "QueueEvents" solution gets the basic idea right, but there are more elegant solutions, like publishing via the repository or the event store. For an example have a look at SimpleCQRS

    You might also find these questions and answers useful:

    CQRS: Storing events and publishing them - how do I do this in a safe way?

    Event Aggregator Error Handling With Rollback


    Update on point 3:

    ... however I read somewhere that domain events should not rely on a specific order of execution.

    Regardless of your way of persisting, the order of events absolutely matters (within an aggregate).

    Now NotifyCustomer behaviour depends on the order being saved in the database, so the PersistOrder event handler should execute first. Is it acceptable that these handlers introduce a property for example that indicates the order of their execution?

    Persisting and handling events are separate concerns - don't persist using an event handler. First persist, then handle.

    0 讨论(0)
  • 2021-02-03 13:38

    Disclaimer: I don't know what I am talking about. ⚠️

    As an alternative to raising events in the ShoppingCartService you could raise events in the OrderRepository.

    As an alternative to queuing domain events in the ShoppingCartService you could queue them in the Order aggregate by inheriting from a base class that provides a AddDomainEvent method.

    public class Order : Aggregate
    {
        public Order(IEnumerable<ShoppingCartItem> cart, Customer customer)
        {
            AddDomainEvent(new OrderCreated(cart, customer))
        }
    }
    
    public abstract class Aggregate
    {
        private List<IDomainEvent> _domainEvents = new List<IDomainEvent>();
    
        public IReadOnlyCollection<IDomainEvent> DomainEvents => _domainEvents.AsReadOnly();
    
        public void AddDomainEvent(IDomainEvent domainEvent)
        {
            _domainEvents.Add(domainEvent);
        }
    }
    
    0 讨论(0)
提交回复
热议问题