2

I have a CQRS system in development that passes the Command to a CommandHandler, which gets an Aggregate from a Repository, and calls a method with the properties of the Command (converted to ValueObjects).

The method then creates the Event internally and registers it in a hash object to be collected and persisted later.

I have some meta data that needs to come from the initial request and be persisted with the resulting Event, and I am loathed to have to pass this through the method on the Aggregate which IMO should be only concerned with the domain itself, and not message related data.

The problem I have is that every single public method in the domain will have to accept this meta object; that seems ridiculous to me. Even a method that normally would have no parameters (like a toggleSomeState() method).

So, my question is, can someone provide a decent example of how the meta data can bypass the Aggregate, yet end up in the Event on the other side?

Update:

Here's an explanation of the meta data. We currently have two Uuids that have been used for authentication, and due to the nature of the domain being a multi-tenanted system, these uuids have to be persisted right the way through the application. Of course, if I have two now, I will have more later ;) This is another reason I want to not pass them into the aggregate methods.

Also, from a comment, I have learned that once an Event has been produced, it is immutable. How then could I be comfortable allowing the system to edit that Event before persistence to add this meta data? Is this one of those occasions of compromise I would have to live with?

1 Answers1

1

There's no magic.

The metadata has a lifetime within the request scope, so you are going to need to trace out some path from where it starts to where it ends.

Now, if it is metadata, then the domain model really shouldn't be concerned with it -- so you would prefer that the path not pass explicitly through the model.

There are at least two possibilities for how to achieve this.

One is to look at the creation of the events themselves - you could use a factory to create the new events, and inject a factory that has been initialized with the metadata. The event factory in effect acts as a collaborating interface between your domain model and the event representations that you store.

(You were already creating events within your domain logic, so the factory has at least implicit existence in your domain; all we are doing is making that existence explicit and giving it request scope).

Another possibility is to consider "appending" the metadata to the representations as you write them. Each of the event representations is transformed by adding the metadata to it, within the scope of the request, but before writing them to the store.

VoiceOfUnreason
  • 34,589
  • 2
  • 44
  • 83