Fat Controller CQRS Diet: Notifications

CQRS NotificationsThis post is in my Fat Controller CQRS Diet series. It demonstrates how to thin your controllers by implementing commands and queries using the MediatR library.

I’m converting the MusicStore application that’s using ASP.NET Core MVC.   All the source code is available on GitHub.

If you’re new to this series, here are earlier posts to get up to speed:

  1. Overview of Series
  2. Simple Query
  3. Simple Command
  4. Command Pipeline

Logging

In the my previous Command Pipeline example, I leveraged StructureMap and the decorator pattern to setup a pipeline.

My pipeline would invoke the actual command handler as well as any classes that implemented the correct IPostRequestHandler<TRequest, TResponse>.

This enabled us to create a AddToCartLogHandler which did our logging that was originally in the ShoppingCartController.AddToCart action method.

Notifications

Another way to implement this is with a Notification (event).

MediatR has this concept built in with a couple interfaces INotification, IAsyncNotification

The concept and how it works with MediatR very similar as a request (Command or Query) and it’s appropriate handler.  The difference with a Notification is it can have many handlers.

  • Request: only one handler
  • Notification: zero to many handlers

Implementation

I’m going to jump back to our AddToCart command.  Instead of it using an IPostRequestHandler<AddToCart, Unit> that I created for our pipeline, I’m going to instead create a notification and publish that notification from MediatR.

First, we need to create a class to represent our notification.  All the class will contain is a property to specify the AlbumId that was added to the shopping cart.

Now we will create a Notification Handler that will accept this new notification object and do the logging.

Finally, our last piece is to Publish a new AlbumAddedToCart notification to MediatR.  We can do so in our AddToCartHandler .

Comments

All the source code for this series is available on GitHub.GitHub

Which do you prefer, Pipeline or notifications? Let me know in the comments or on Twitter.


  • Hi Derek,

    great article.
    I’ve followed pretty much the same path but I’ve chosen to publish events in my MVC/Api controllers when I get back the result from the executed command.
    I don’t know if this is the best choise but it seems kind of not-right to publish event from the command handler.
    Could you help me to understand why you followed this path ?

    Thanks,

    Alberto

    • To be honest, I hadn’t really thought about publishing from the controller action. Interesting, makes me think.

      I can see how not taking a dependency on IMediator in your request handler would be nice, however I guess the question would be how important is it that an event/notification is published? If you require it to be published, then having it outside of your handler poses a problem if you ever invoke that request somewhere else.

      • That makes sense.

        Thanks.

    • For simple apps, you can use a Controller as an Application Service (use case host) and publish events from it, but if you’re building apps with multiples UIs (and multiple frameworks), it’s easier to have the business use case into its own app service and let that service care about publishing.

  • beton

    Very clean solution. Keep them coming 🙂 Cheers

  • Vegar Vikan

    I’m curious about why you would prefer this path over the pipeline path?
    Or is this just teaching ‘another way’ without any preferences?

    On one side, you’ll have a little more control in streamlining the event for each case, but an generic `INotification` implementation in the pipeline would remove the need for an explicit `Publish` in your code.

    • This was more just to show another way as an example. But yes, very valid point is you could have the notification published from the Pipeline.

      • James

        I like the combo, the pipeline (or one implemented directly in the handler) doing the “write” ops & the notifications for related but not critical path operations.

  • Nice write up. Thanks for sharing!

    What do you think of similar post – this time I called it round shape architecture

    http://blog.tech-fellow.net/2016/10/30/baking-round-shaped-software-mapping-to-the-code/

  • Lol at Unit. Personally I’m using a `NoResult` type. I’m trying not to leak F# into C# 🙂

  • Pingback: The week in .NET – On .NET on MyGet – FlexViewer – I Expect You To Die | .NET Blog()

  • Pingback: Szumma #070 – 2016 50. hét | d/fuel()