I have tried the CQRS pattern using MediatR and am loving the clean state in which applications am working on are transforming. In all the examples i have seen and used, I always do
await Mediator.Send(command);
It's been same for the queries as well
var data = await Mediator.Send(queryObject);
I just realized there's Mediator.Publish as well which after searching seems to me to be doing the same thing. I am trying to understand what the difference between the Mediator.Send and Mediator.Publish is. I have read the MediatR library docs and I still don't understand what the difference between these are. Kindly help me understand the difference.
Thanks for your help
MediatR has two kinds of messages it dispatches:
- Request/response messages, dispatched to a single handler
- Notification messages, dispatched to multiple handlers
Send
may return a response, but do not have to do it.Publish
never return the result.You are sending requests (sometimes called commands) by _mediator.Send({command})
to exactly one concrete handler. It may be e.g. command that saves a new product to the database. It is often a request from the user (frontend/API) or sometimes it may be internal command in your system given by other service in a synchronous way. It is always expected that the command will be executed immediately and you will receive some proper result or error to immediately inform the client about some failures.
You are publishing notifications (often called events) by _mediator.Publish({event})
to zero, one or many handlers. You used notifications when you want to publish some information and you do not know who needs that. E.g. NewProductEvent
which is published after successfully adding product to your Warehouse Module. Few other contexts want to subscribe the information and e.g. send email to a client that a new product is available or create some default configuration for the product in your Store Module (which payment and delivery are available for the product). You may use notifications in a synchronous way. All data will be saved in one transaction (product and store configuration) or you may use some async pattern with service bus or/and sagas. In the second case (asynchronous) you must manually handle cases when something wrong happens in other services or contexts which subscribe to your notification.
Example scenario: Default configuration was not created.
A good example of using mediatR you will find in e.g. Ordering microservice in EShopOnContainers by Microsoft: github. You will see an example usage of CQRS and DDD with EF core and ASP Net.