Could you tell me your opinion that which layer is the right one to place domain event handlers in DDD? For example, I have application service to add a new contract and I'd like to send an email notification to the contact person, when the contract has added, so is that email sender (which handle ContractAdded event) application service or domain service or something else?
DDD: Where to place domain event handlers
domain-driven-designevent
Related Solutions
I think you need to separate two types of validation in this case; domain validation and application validation.
Application validation is what you have when you verify that the command property 'text' is between 20 and 200 characters; so you validate this with the GUI and with a view-model-validator that also executes at the server after a POST. The same goes for e-mail (btw, I hope you realize that an e-mail such as `32.d+"Hello World .42"@mindomän.local" is a valid according to the RFC).
Then you have another validation; check that article exists - you have to ask yourself the question why the article should not exist if there is indeed a command sent from the GUI that is about attaching a comment to it. Was your GUI eventually consistent and you have an aggregate root, the article, that can be physically deleted from the data store? In that case you just move the command to the error queue because the command handler fails to load the aggregate root.
In the above case, you would have infrastructure that handles poison messages - they would for example retry the message 1-5 times and then move it to a poision queue where you could manually inspect the collection of messages and re-dispatch those relevant. It's a good thing to monitor.
So now we've discussed:
Application validation
- With javascript in the GUI
- With MVC-validation at the web server
Missing aggregate root + poison queues
What about commands that are out of sync with the domain? Perhaps you have a rule in your domain logic saying that after 5 comments to an article, only comments below 400 characters are allowed, but one guy was too late with the 5th comment and got to be the 6th - GUI didn't catch it because it was not consistent with the domain at the point of him sending his command - in this case you have a 'validation failure' as a part of your domain logic and you would return the corresponding failure event.
The event could be in the form of a message onto a message broker or your custom dispatcher. The web server, if the application is monolithic, could synchronously listen for both a success event and the failure event mentioned and display the appropriate view/partial.
Often you have custom event that means failure for many types of commands, and it is this event that you subscribe to from the web server's perspective.
In the system that we are working on, we're doing request-response with commands/events over a MassTransit+RabbitMQ message bus+broker and we have an event in this particular domain (modelling a workflow in part) that is named InvalidStateTransitionError
. Most commands that try to move along an edge in the state graph may cause this event to happen. In our case, we're modelling the GUI after an eventually consistent paradigm, and so we send the user to a 'command accepted' page and thereafter let the web server's views update passively through event subscriptions. It should be mentioned that we are also doing event-sourcing in the aggregate roots (and will be doing for sagas as well).
So you see, a lot of the validation you are talking about are actually application-type validations, not actual domain logic. There's no problem in having a simple domain model if your domain is simple but you are doing DDD. As you continue modelling your domain, however, you'll discover that the domain might not be as simple as it first turned out. In many cases the aggregate root/entity might just accept a method invocation caused by a command and change some of its state without even performing any validation - especially if you trust your commands like you'd do if you validate them in the web server that you control.
I can recommand watching the two presentations on DDD from Norwegian Developer Conference 2011 and also Greg's presentation at Öredev 2010.
Cheers, Henke
You are allowed to create your read model projections as necessary, and you can either read the current read model state to update it, or, you can set up a pipeline where you read & update internal read model state, and from that (re)create the read model projections.
In some sense, you are always updating your read model picture of the world based on the last picture of that world + the effect of applying the next event. So, reading the read model is natural.
However, any way you do it, you have to be sure to consume the events (apply the events from the event source/log to the read model) in (the proper) order and using enough transactional atomicity so that downstream consumers always see a complete view of the state, which is either 100% the old state before applying an event, or 100% the new state after applying an event.
The eventual consistency means that when incoming events cease for a short while, the read model pipeline catches up. However, it would be bad to expose via in the read model, an inconsistent state (a state that never was a true picture of the world) say in which, either some change is only partially applied to the read model projections, or the effects of a later event is shown before the effects of an earlier one; this even if the state eventually converges on a true picture of the world.
You are still allowed to read the read model during update of the read model from the events in the event log.
However, there are some proponents of event enrichment, in which you do what you're saying for option 1; see: http://www.lavinski.me/generating-read-models-with-event-sourcing/, https://seabites.wordpress.com/2013/06/09/event-enrichment/
I think I'd still see prefer to see this as a function of the read model in generating its denormalized projections rather than a domain function, since it is not really a business function per se, but rather one of creating the right view, and keeping it wholly in the read model alone will decouple your command and query more from a maintenance point of view.
Best Answer
I place domain event handlers in application layer.
Domain event is a way to tell the outside layers (or outside world) that something happened in the domain layer. What to do with the event depends on the application. Application may notify user about changes or may call another domain to do something. Application is responsible for orchestrating domain operations in reaction on user actions, web requests or domain events.