Skip to content

Instantly share code, notes, and snippets.

@pjvds
Created August 25, 2010 05:55
Show Gist options
  • Save pjvds/548944 to your computer and use it in GitHub Desktop.
Save pjvds/548944 to your computer and use it in GitHub Desktop.

Adding Entity Support to Ncqrs

Goal

Add entity support to Ncqrs.

Why we need it

An aggregate root covers all state changes by events. These events are stored and aggregate roots can rebuild themself from these events by re-applying them.

Since aggregate roots are the only objects that can source these events, they can become really fat. They become fat in two ways:

  1. The aggregate must also cover all the state changes of child objects. This means all methods that are defined on child objects should be exposed by methods on the aggregate root.

  2. The aggregate must contain event handlers for all the events, also the ones that are related to the change of an entity state.

We need a way to solve this issue. One way is to add Entity support, where entities can handle a part of the event raising and handling.

Adding entity support to Ncqrs

The idea behind entity support is that an aggregate root should be able to have entities that handle there own events. Entities that raise there own events, and can rebuild themself from this. Event handling inside the entities should be as easy as in the aggregate roots, including convention and fluent mapping support.

We should be able to do this by introducing an Entity base class that handles this blumbing code.

Entity characteristics

An entity is always part of an aggregate root. This can be direct, or indirect. It also covers all state changes by events and can rebuild itself from it. It does this in the same way as an aggregate root does, but it use the infrastructure of the aggregate root. It will not apply the events to itself, but to the aggregate root. It will also registering the event handlers there, so when it applies an event to the aggregate root that belongs to the entity, this handler will be called.

It will handle all the events that have the correct type AND the correct entity id. This to support multiple entities from the same type (so, also firing the same event).

One other difference is that it does not raise an event when created. The owner of the entity is responsible for that. Since it cannot describe the context from why this happened.

Current implementation

Szymon Pobiega has already implemented this in entities branch. The simplicity of this is really great and I prefer a solution based on this. In the testing project you find a small example that uses this new spiked part of Ncqrs.

The problem

Although the code in the entities branch from Szymon is a great start point for entity support, I have problems while test driving this with sub-entity support.

The problem is identification. Entities receive all events of a certain type, eq. OrderLinePriceChanged. When this event gets applied to the aggregate root, it sends it to the registered handlers. It can be that there are multiple entities that have registered a handler for that type. So, they will all be called and the one that sees his own ID in the event will process it. Since entities in this context do not have an identifier, they are solely responsible for handling, or skipping, events. Sub entities have to know the id of there parent to do this identification.

Possible solution

To solve the identification problem we could add an EntityId property to the Entity class. When we use a Guid as a type for this property the entity does not need the parent id (or in some cases even the parent parent id).

The good side

This easilly solves the problem. Entities only have to check whether the event contains there id.

This id is also great to support merging when there is a conflict. Since the id is not an incrementing auto number or something that can be the same in some concurrent situations.

The bad side

The events also contain the entity id that is a guid. Guids aren't always accepted as identifiers. We can solve this by adding a good explanation why it isn't bad.

@promontis
Copy link

I like it! When will it be pushed?

@pjvds
Copy link
Author

pjvds commented Aug 26, 2010

Hope soon. I will give this a try this weekend. Already spiked a few things. Will post an update in the Ncqrs-dev group when ready for test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment