Question

I am trying to understand the Domain Event pattern illustrated by Udi Dahan with regard to adding new domain entities in a certain situation.

Now normally with entities I would create them and then add them via repository. I assume I would still do this?

My example is we normally add assets to the system. Like this:

 var asset= new Asset();
/*bunch of prop setting*/
 _assetRepository.Add(asset);

However asset creation is an event that we want to follow certain processes as a result of. Therefore it was suggested by developer we no longer need to do this as it could be handled by domain event:

var asset= new Asset();
   /*bunch of prop setting*/
asset.Create(location);

Now a create method would raise an event and be handled by a create event handler that basically just inserts it into the repo and does some other stuff email the warehouse manager of the create location etc.

However having a create event on the asset looks pretty active record to me. However in the domain people talk about new assets being created. So we were not sure.

Thoughts?

Was it helpful?

Solution

The created domain event should be raised in the constructor of the Asset class because that is when that particular entity is created. In your current implementation, this would be erroneous because the Asset entity provides a parameterless constructor. Instead, create a constructor which has all required properties as parameters thereby preventing creation of an Asset entity in an inconsistent state. It could look like this:

public class Asset
{
  public Asset(string prop1, decimal prop2) 
  {
    this.Prop1 = prop1;
    this.Prop2 = prop2;
    DomainEvents.Raise(new AssetCreated(prop1, prop2));
  }

  public string Id { get; private set; }
  public string Prop1 { get; private set; }
  public decimal Prop2 { get; private set; }
}

You still have to persist the entity using the repository after creating it. This can be problematic because the handlers for the AssetCreated cannot reference its ID since it is not yet assigned when they are notified. If using event sourcing, then the creation event would be explicitly stored in the underlying event store.

OTHER TIPS

I've been struggling for this problem for quite a long time. But no good solution. I think,

  • A domain event shouldn't be published or handled before the aggregate it belongs to being successfully persisted
  • It's not the application layer's responsibility to publish any domain events

So far, I think the best approach is to take advantage of AOP. We can "fire" events in the aggregate, but instead of dispatching them instantly, we keep it in a queue, and really dispatch it after the corresponding transaction successes.
We can define a custom @Transactional interceptor to achieve this, thus keeping the app service from knowning any concept of "event publishing".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top