title: Domain Driven Design (DDD): Domain Event Handlers – Where to place them?
body: <p>I am confused about where to handle domain events in an application that is based on the hexagonal architecture. I am talking about the bounded-context-internal domain events, and not about inter-context integration/application/public events.</p>
  <p><strong>Background</strong></p>
  <p>As far as I understand, application logic (i.e. use case logic, workflow logic, interaction with infrastructure etc.) is where command handlers belong, because they are specific to a certain application design and/or UI design. Command handlers then call into the domain layer, where all the domain logic resides (domain services, aggregates, domain events). The domain layer should be independent of specific application workflows and/or UI design.</p>
  <p>In many resources (blogs, books) I find that people implement domain event handlers in the application layer, similar to command handlers. This is because the handling of a domain event should be done in its own transaction. And since it could influence other aggregates, these aggregates must be loaded via infrastructure first. The key point however, is this: <em>The domain event is torn apart and turned into a series of method calls to aggregates</em>. This important translation resides in the application layer only.</p>
  <p><strong>Question</strong></p>
  <p>I consider the knowledge about <em>what domain events cause what effects on other aggregates</em> as an integral part of the domain knowledge itself. If I were to delete everything except my domain layer, shouldn't that knowledge be retained somewhere? In my view, we should place domain event handlers directly in the domain layer itself:</p>
  <ul>
  <li><p>They could be domain services which receive both a domain event and an aggregate that might be affected by it, and transform the domain event into one or many method calls.</p>
  </li>
  <li><p>They could be methods on aggregates themselves which directly consume the entire domain event (i.e. the signature contains the domain event type) and do whatever they want with it.</p>
  </li>
  </ul>
  <p>Of course, in order to load the affected aggregate, we still need a corresponding handler in the application layer. This handler only starts a new transaction, loads the interested aggregate and calls into the domain layer.</p>
  <p>Since I have never seen this mentioned anywhere, I wonder if I got something wrong about DDD, domain events or the difference between application layer and domain layer.</p>
  <p><strong>EDIT: Examples</strong></p>
  <p>Let's start with this commonly used approach:</p>
  <pre class="lang-cs prettyprint-override"><code>// in application layer service (called by adapter)
  public void HandleDomainEvent(OrderCreatedDomainEvent event) {
      var restaurant = this.restaurantRepository.getByOrderKind(event.kind);
      restaurant.prepareMeal(); // Translate the event into a (very different) command - I consider this important business knowledge that now is only in the application layer.
      this.mailService.notifyStakeholders();
  }
  </code></pre>
  <p>How about this one instead?</p>
  <pre class="lang-cs prettyprint-override"><code>// in application layer service (called by adapter)
  public void HandleDomainEvent(OrderCreatedDomainEvent event) {
      var restaurant = this.restaurantRepository.getByOrderKind(event.kind);
      this.restaurantDomainService.HandleDomainEvent(event, restaurant);
      this.mailService.notifyStakeholders();
  }
  
  // in domain layer handler (called by above)
  public void HandleDomainEvent(OrderCreatedDomainEvent event, Restaurant restaurant) {
      restaurant.prepareMeal(); // Now this translation knowledge (call it policy) is preserved in only the domain layer.
  }
  </code></pre>