My question is related to CQRS (Command and Query Responsibility Segregation) and mechanism that builds read model (views). As far as I understand read model is built by event handlers. These handlers (also called denormalizers) receive domain events and use these events to build different views of data.
Specific event carries information about change done in domain model. I think that this information is not sufficient in some cases to build view - i.e. not changed fields, not changed entities are missing in such event etc.
So my question is:
Is it allowed that denormalizer responsible for building read model accesses not only events but also:
- changed entity referenced directly in event?
- changed aggregated root and any entity related to this aggregate?
- any entity fetched from repository?
- any view?
What is your opinion about allowed dependencies for event handlers (denormalizers)?
edit: Just added simple example to the question above:
Suppose the following model:
AR: ProductOffering * name * description * category * price
AR: Customer * name * type * method: purchaseProduct(productOffering) that emits ProductPurchasedByCustomer event
entity: ProductInstance * customer * productOffering
event: ProductPurchasedByCustomer * customerId * productOfferingId
view: ProductInventoryView * customerId * productOfferingId * customerType * productOfferingName * productOfferingCategory * price
How to build ProductInventoryView using only ProductPurchasedByCustomer event? How c开发者_如何学JAVAan I write denormalizer to put into view information about customerType, productOfferingName etc? Should I lookup additional information about customerType and productOfferingName from different views?
If an event consumer requires more information, it's okay for an event producer to provide that required information, eventhough it hasn't changed. Eventsourcing should not be treated like an ORM. Mind you things can become tricky with regard to how you get that information, but lets not complicate things (yet). The eventhandlers can use the state (data) of the read model if it's not provided by the event. But doing so requires you to know if and which data you can use. It requires you to couple time to the data. Messages/events are likely to be processed out of order. So, providing information in the event, pertaining to the event, is much easier. Try do that before doing anything else. Don't try to access your domain from the eventhandlers specific to your read model, that's just nasty coupling. One last thing, it's okay for aggregates to copy data from other aggregates to provide the data you need in your events. Mind you that from then on you'll have to start thinking on how to keep that data fresh in the aggregates that copied it in the first place. Probably confused you some more ...
According to my understanding:
changed entity referenced directly in event?
no
changed aggregate root and any entity related to this aggregate?
no
any entity fetched from domain repository?
no
any report that is not related to event
no
changed entity report for entity that is referenced directly in event?
yes
changed aggregate root report and any entity report related to aggregate referenced in event?
yes
because denormalizer is supposed to know nothing about domain repository and update related reports only.
if it seems that report is unrelated but it must be updated, that's a code smell - likely You are designing Your model/reports incorrectly.
精彩评论