I'm trying to get my head around DDDD in Greg Young's style.
There is much talk about how to implement DDDD with CQRS+EventSourcing and there are some sample implementations ... and altogether it can be quite confusing...
In Gregs view aggregates don't have getters or setters - just state-changing methods which emit an corresponding event.
Basicly a event decribes a state-transitions that happend in the past. It's data describes what changed.
Some say, that this data can be "enriched" by additional data.
Where can this additional data come from?
i.e. I have User
and Usergroup
- both aggregate roots (can exist independently, have identity). User
has a method called AddToUsergroup
.
public class User : AggregateRoot
{
// ...
public void AddToUsergroup(Usergroup usergroup)
{
// validate state
RaiseEvent(new UserJoinedUsergroup(this.Id, usergroup.Id));
}
// ...
}
public class Usergroup : AggregateRoot
{
private string _displayName;
// ...
public void ChangeDisplayName(string displayName)
{
// validate state
RaiseEvent(new DisplayNameChanged(this.Id, displayName));
}
public void Apply(DisplayNameChanged e)
{
this._displayName = e.DisplayName;
}
// ...
}
If I would like to "enrich" the event with the name of the Usergroup (for debug reasons or something like this), how would I do that?
Injecting such things as repositories into User
is not allowed (am I right here?!?), like
And (little off-topic but the sample is here)
AddToUsergroup
take an Guid instead of an full aggregate root?Looking forward to your answers!
Lg
warappa
A Domain Event is an event that is spawned from this model that is a result of a decision within the domain. Within the model our Aggregates have the role of maintaining business rules and this is where we implement decision points in our model, so the Aggregates are also responsible for creating the Domain Events.
A domain event is, something that happened in the domain that you want other parts of the same domain (in-process) to be aware of. The notified parts usually react somehow to the events. An important benefit of domain events is that side effects can be expressed explicitly.
Domain-Driven Design(DDD) is a collection of principles and patterns that help developers craft elegant object systems. Properly applied it can lead to software abstractions called domain models. These models encapsulate complex business logic, closing the gap between business reality and code.
An aggregate is a cluster of associated objects that we treat as a unit for the purpose of data changes. Each aggregate has a root and a boundary. The boundary defines what is inside the aggregate. The root is a single, specific entity contained in the aggregate.
Should something like repositories be injected to aggregate roots?
No and there is no need to in this case. It can be appropriate to pass a domain service to a behavioral method on an aggregate, but again, not needed in this case.
Should a event only use data available through parameters and internal state of the aggregate?
Yes, the original domain event should be such that it can be easily built by the aggregate and can be replayed in a deterministic fashion.
Should events only contain the minimum data describing the state-change?
Yes. However, to address requirements of external subscribers, this is where content enricher comes into play. To dispatch a domain event externally, it is first committed to the event store then you can dispatch in the same tx or have an out of process mechanism which publishes events externally. At the point of publishing externally, you will normally use a different contract for the message since subscribers may need more than what is on the domain event itself. In this case, you need the user group name. The publisher, then, can pull up the user group name and place that data into the enriched event. This publisher can have access to a read-model repository for user groups which would allow it to retrieve the name.
Should AddToUsergroup take an Guid instead of an full aggregate root?
Yes. Passing the entire aggregate may not be possible and also creates the illusion that something other than the ID may be used, which should not be the case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With