Domain Events are Super Ice
Domain events are frozen. They don't change. They're so cold that if an event needs to change we instead version up a new event and leave the old one alone.
They're SO cold in fact that they freeze whatever they touch. Freezing strings and shit is no big deal, because that's the language's problem... A bigger problem is when they freeze your whole domain model's value types.
What happens if a domain event is full of your nice rich value types and a value type needs to change? That's going to be a problem because they're implemented in frozen code. It's likely that the kinds of values that are in one domain object are going to be in multiple. Are you going to change the value and then create new versions of multiple events? Are you going to create a new version of that value?
Domain events are frozen, anything they touch freezes, don't freeze your value types.
Slower Bulk Instantiation
Do you need to rebuild a projection? Do you need to process anything with a bunch of events? It's going to be much faster with primitive types.
Primitive values can be auto-serialized trivially. Complex serialization systems are a drag. It can be done, I've done it, it's ok. It's better without.
If the intent for the event came through your domain then your domain values are responsible for consistency. It's entirely possible to have static factory methods on your events that allow them to be built from domain value types etc.
What about data that comes from external services? Webhooks? Do we really want to validate that for consistency? Are we sure that we know the specifics of that services' types?
That external service validates their data and what we got IS what they sent. Better to take what they sent than just reject it. Otherwise you're just giving up what information you could have had based on a disagreement. I think that we should be a bit more mature than that.
Tune in for the next episode called, "Reasons to use Value Types in Domain Events".
software, business, and game design