I have implemented a CreateEdit query/command (based on Contoso Univerity example) but I would also like to add an additional handler to send a confirmation email after a successfully creating or updating an entity.
I have looked at the AsyncNotificationHandler to get all the handlers to respond but the notification handler cant return values?
I'm assuming my post edit controller code would look like this:
var id = await _mediator.Publish(command);
But it looks like notification command can't return values. I am obviously missing something but can't figure it out?
I this even possible?
Make a clear distinction between commands and events, something like this:
_mediatr.Send(new DoSomething());
DoSomethingHandler:
// do something
// ...
_mediatr.Publish(new SomethingHasHappened());
SomethingHasHappenedHandler:
// send confirmation e-mail.
@remcoros Good idea. One question though how would I capture a failure when trying to send an email as the Publish event cannot return anything?
Publishing notifications are fire-and-forget.
If you want to capture a failure on the calling side, it's not "fire and forget" and you shouldn't use notifications.
Imo, sending an e-mail should be fire-and-forget from the call site. You would handle a failure by adding failed e-mails to a queue and have some other (background) service retry sending the e-mail.
If that's too much for your scenario, then you're back to chaining commands or handle everything inside a single handler.
Jimmy has some nice blogs about these subjects here: https://jimmybogard.com/refactoring-towards-resilience-a-primer/
As far as I understand MediatR, exceptions that happen inside notification handlers won't get caught. So notifications aren't truly fire-and-forget; we still wait for them to complete, and there can be exceptions that bubble up the stack. That means that it is, in fact, possible to do exception handling around the Publish call, e.g. handle some sort of EmailSendingFailedException.
But I completely agree that it shouldn't be done that way.
Ideally, write your notification handlers in a way so that they do as little work as possible, something that is fast and will never crash. That way you don't have to do any exception handling around notification handlers or wait too long for them to complete.
To illustrate this principle on your scenario:
Everyone, thank you for some great tips and advice.
Most helpful comment
As far as I understand MediatR, exceptions that happen inside notification handlers won't get caught. So notifications aren't truly fire-and-forget; we still wait for them to complete, and there can be exceptions that bubble up the stack. That means that it is, in fact, possible to do exception handling around the
Publishcall, e.g. handle some sort ofEmailSendingFailedException.But I completely agree that it shouldn't be done that way.
Ideally, write your notification handlers in a way so that they do as little work as possible, something that is fast and will never crash. That way you don't have to do any exception handling around notification handlers or wait too long for them to complete.
To illustrate this principle on your scenario: