title: Persistence and Domain Events with persistence ignorant objects
body: <p>I've been studying on domain driven design in conjunction with <a href="http://www.udidahan.com/2009/06/14/domain-events-salvation/" rel="noreferrer">domain events</a>. I really like the separations of concerns those events provide. I ran into an issue with the order of persisting a domain object and raising domain events. I would like to raise events in the domain objects, yet I want them to be persistence ignorant.</p>
  
  <p>I've created a basic <code>ShoppingCartService</code>, with this <code>Checkout</code> method:</p>
  
  <pre><code>public void Checkout(IEnumerable&lt;ShoppingCartItem&gt; cart, Customer customer)
  {
      var order = new Order(cart, customer);
  
      _orderRepositorty.Add(order);
      _unitOfWork.Commit();
  }
  </code></pre>
  
  <p>In this example, the constructor of <code>Order</code> would raise an <code>OrderCreated</code> event which can be handled by certain handlers. However, I don't want those events to be raised when the entity is not yet persisted or when persisting somehow fails.</p>
  
  <p>To solve this issue I have figured several solutions:</p>
  
  <p><strong>1. Raise events in the service:</strong></p>
  
  <p>Instead of raising the event in the domain object, I could raise events in the service. In this case, the <code>Checkout</code> method would raise the <code>OrderCreated</code> event. One of the downsides of this approach is that by at looking the <code>Order</code> domain object, it isn't clear which events are raised by what methods. Also, a developer has to remember to raise the event when an order is created elsewhere. It doesn't feel right.
  <hr />
  <strong>2. Queue domain events</strong></p>
  
  <p>Another option is to queue domain events and raise them when persisting succeeded. This could be achieved by a <code>using</code> statement for example:</p>
  
  <pre><code>using (DomainEvents.QueueEvents&lt;OrderCreated&gt;())
  {
      var order = new Order(cart, customer);
  
      _orderRepositorty.Add(order);
      _unitOfWork.Commit();
  }
  </code></pre>
  
  <p>The <code>QueueEvents&lt;T&gt;</code> method would set a boolean to <code>true</code> and the <code>DomainEvents.Raise&lt;T&gt;</code> method would queue the event rather than executing it directly. In the dispose callback of <code>QueueEvent&lt;T&gt;</code>, the queued events are executed which makes sure that the persisting already happened. This seems rather tricky and it required the service to know which event is being raised in the domain object. In the example I provided it also only supports one type of event to be raised, however, this could be worked around.
  <hr>
  <strong>3. Persist in domain event</strong></p>
  
  <p>I could persist the object using a domain event. This seems okay, except for the fact that the event handler persisting the object should execute first, however I read somewhere that domain events should not rely on a specific order of execution. Perhaps that is not that important and domain events could somehow know in which order the handlers should execute. For example: suppose I have an interface defining a domain event <em>handler</em>, an implementation would look like this:</p>
  
  <pre><code>public class NotifyCustomer : IDomainEventHandler&lt;OrderCreated&gt;
  {
     public void Handle(OrderCreated args)
     {
         // ...
     }
  }
  </code></pre>
  
  <p>When I want to handle persisting in using an event handler too, I would create another handler, deriving from the same interface:</p>
  
  <pre><code>public class PersistOrder : IDomainEventHandler&lt;OrderCreated&gt;
      {
         public void Handle(OrderCreated args)
         {
             // ...
         }
      }
  }
  </code></pre>
  
  <p>Now <code>NotifyCustomer</code> behaviour depends on the order being saved in the database, so the <code>PersistOrder</code> event handler should execute first. Is it acceptable that these handlers introduce a property for example that indicates the order of their execution? A snap from the implementation of the <code>DomainEvents.Raise&lt;OrderCreated&gt;()</code> method:</p>
  
  <pre><code>foreach (var handler in Container.ResolveAll&lt;IDomainEventHandler&lt;OrderCreated&gt;&gt;().OrderBy(h =&gt; h.Order))
  {
      handler.Handle(args);
  }
  </code></pre>
  
  <p><hr>
  Now my question is, do I have any other options? Am I missing something? And what do you think of the solutions I proposed?</p>