Sure thing Bram, glad to help out!
I can imagine further questions arise with conversations like this, so although you have a lot of questions, I’ll try to answer them one by one regardless.
I’ll follow the order you’ve posted them in, quoting the exact line(s) referring to the question.
So, here goes:
From my point of view, the scope of a bounded context exists on several levels.
For example, let’s envision an office building for a bank.
Each floor is a separate department.
And within a department, you have separate teams.
Each of these teams might form its own bounded context, given the subject they’re working on.
Although they’re their own bounded context, they still need to communicate with the other teams in their department. Or in different words, with the other bounded contexts within their floor.
A similar point can be made for inter-department communication. Just as with the teams of a department having separate bounded contexts, these departments should just as well share consciously with the other departments. With this line of thought, a department becomes a bounded context containing bounded contexts.
Given this conceptual layering of bounded contexts, I feel that on each level domain, events make sense. It depends on the perspective on how you call them, as for a team, the department events most definitely are milestone events. But for the department context, those are “just domain events.”
Although this is my POV, thus domain events exist on several levels. The most important thing is that you and your team develop a working naming scheme. If you opt for domain events
within the context and integration events
between the contexts, who am I to say that’s right or wrong. As long as the paradigm is followed throughout, you should be good.
I get the gist here, although I would personally still prefer to keep events as flat as possible. Regardless of whether they’re within one bounded context or shared between bounded contexts. So, option/opinion two from your description.
The “commoners” like Address
and Money
are, in my mind, fair to be shared since they’ll likely not change too often. But anything else I’d try to steer away from if reasonable. It’s good to gauge how important the Value Object is to the specific bounded context. If it nears things like Address
/Money
, it should be fair to include. However, if it doesn’t, then the “win” you gain by reusing the class during development might just bite you with version compatibility later on.
Note that this argument holds for Commands, Queries, Query Responses, and Events.
I am not entirely sure why the state in your events is separated between command and read model fields. I would assume that in most cases, the decisions made by your Command Model result in facts that can be shared with anybody inside the context. Regardless of whether the component subscribing to the event is an Event Sourcing Handler or an Event Handler.
However, if this is a hard requirement in your application, I think I would personally opt for option one. Option two feels like polluting your event store too much.