3

So much of the benefits around Event Sourcing apply to the being able to audit the system and show an aggregate's state throughout its life. However, I haven't been able to find any examples of where to record who issued the command and when with was issued.

I have been doing a lot of my learning by dissecting the CQRS Journey on MSDN. The only place that I see any indication of who created something is in the ConferenceEvent class.

public abstract class ConferenceEvent : IEvent
{
    public Guid SourceId { get; set; }

    // **snip**

    public Owner Owner { get; set; }
}

I cannot find any indication that when the event occurs is ever recorded. Should every Command have a CreatedOn and CreatedBy which then gets propagated to the Event. Then, when rehydrating the aggregate, which would be inherited from the sample below, the events would know which who and when fields to populate?

public abstract class EventSourced : IEventSourced
{
    [Required]
    public string CreatedBy { get; set; }
    public DateTime CreatedOn { get; set; }
    public string LastModifiedBy { get; set; }
    public DateTime? LastModifiedOn { get; set; }
    public string DeletedOn { get; set; }
    public DateTime? DeletedBy { get; set; }
}

Each event seems to intuitively be the why while containing the information for the what and where; but what for the other two dubya's?

drovani
  • 133
  • 5

1 Answers1

2

Where to store the “Who” and “When” of a Command and/or Event?

As you perhaps are suggesting, store the who and when in the Event Store, right along with the event (what). In fact, the who and when are integral parts of the command event.

Then, when rehydrating the aggregate, which would be inherited from the sample below, the events would know which who and when fields to populate?

It is not necessarily required that the aggregates maintain all those fields; that is only required if your domain (and hence domain model) needs it.

The events themselves, which serve for audit (as well as replay as needed to rebuild the write-model) contain the necessary who and when.

That who and when is used along with the command in each event by the business logic to advance the state of aggregates.

However, the aggregate does not necessarily have to maintain created by and last modified by, unless the domain needs that.

A comprehensive audit would necessarily look at the whole trail of events directly out of the Event Store, rather than relying on only, for example, the latest modified-by for an aggregate; this means the aggregate does not have to store those fields for specifically for audit, and so does not necessarily have to store latest modified-by information at all in the write-model unless the domain model otherwise requires it.

... the events would know which who and when fields to populate?

The events don't "know"; they are fairly simple immutable objects accepted into the append-only Event Store.

Rather it is the business logic in the domain model that understands how to play events into the current write-model of CQRS; that is, how aggregates (whose latest/current state is stored in the write-model) are updated in response to events containing change commands (what), with references to various aggregates (where, in some sense), and having author identity (who requested), and timing (when requested).

The why is that the client requested the change command, which was accepted by the system as an event and stored in the events store. (We could ask the meta why did the client want to do that, but that is deeper than CQRS+ES can go!)

Erik Eidt
  • 33,282
  • 5
  • 57
  • 91