Fat Controller CQRS Diet: Command Pipeline

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

For demonstration, 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 in this series:

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

Pipelines

In both the new  Query and Commands handlers wrote in prior posts, there was one thing standing out that really didn’t belong.

Logging

For reference, here was our AddToCartHandler that did some logging at the end of the method.

This really isn’t a concern of our AddToCartHandler.  One way we can separate logging out is by having our Command go through another handler after it’s been executed.  If we think about this a bit more broad, we can take it a step further and create a pipeline for our Command that can go through various handlers prior and after the main AddToCartHandler.

Video

If you prefer, I have a video tutorial that follows this blog post.

Decorators

One way to accomplish this is to use Decorators.  A decorator is nothing more than wrapper around our main handler.

In our example, we are going to use StructureMap.  In your project.json, add the following dependencies.

Next in our Startup.cs we are going to configure StructureMap in the IServiceProvider ConfigureServices(IServiceCollection) method.

The gist is we are going to Decorate/Wrap any ICancellableAsyncRequestHandler<TRequest,TResponse> in a Pipeline<TRequest,TResponse> (which we will create next).

Here is our implementation of the Pipeline<TRequest,TResponse>

It will take the primary request as the first argument in the ctor, and then a array of IPostRequestHandler<TRequest,TResponse>, which we will create next to define our logging handlers.

Log Handler

We now have everything in place to separate the logging from our AddToCartHandler.

All we need to know is create a class that will implement IPostRequestHandler<AddToCart,Unit> and it will be invoked after the AddToCartHandler.

Now we can jump back over to our AddToCartHandler and remove the ILogger and the logging code.

Validation, Authorization, Whatever

Hopefully now you can see that we could extend this to have pre-handlers that may do data validation, authorization or whatever other responsibilities that probably shouldn’t be in your main handler.

Comments

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

If have another way of creating a pipeline or separating concerns from your handlers, please leave comment or let me know on twitter.


Fat Controller CQRS Diet: Simple Command

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

For demonstration, I’m converting the MusicStore application that’s using ASP.NET Core MVC.

If you’re new to this series, here are earlier posts in this series:

  1. Overview of Series
  2. Simple Query

Simple Command

A command is request to change the state of our domain.

The first controller action we are going to rewrite is ShoppingCartController.AddToCart

Here is what the method originally looked like this.

As with our simple query, there are a couple things going on here.

  1. MVC is handling the albumId which is pass as an parameter to the method.
  2. We do some data access to get the album out of our EF DbContext
  3. Pass the album to our ShoppingCart
  4. Logging
  5. Return a redirect to the Index action

Extract to Command

What we want to extract are the aspects that MVC is handling.  From the list above it’s the AlbumId being passed the URL/Route and then redirecting to the Index action.

Everything else is our feature, so let’s extract it into a command.

To do so, we need two pieces of information to add to our Request/Command.  The CartId and the AlbumId.

So we will create our Request/Command to contain that data.

Command Handler

Now we can create our handler for this Request/Command.  Basically we are going to extract the majority of the code that was inside our Controller Action and put it into our handler.

You’ll notice we have our constructor take a couple dependencies on our DbContext and the ILogger.

Thin Controller

Now we can jump back to our controller and create our AddToCart Request/Command and send to the Mediator, which will invoke our Handler.

Feature Coupling

We’ve removed coupling of the the MVC framework from our feature code.  We can now create AddToCart Request/Command from other locations and send along to the mediator to have it invoked.

Next

That’s a very simple command endpoint that we moved our logic to a Command Handler using MediatR.

Next up we we will handle a more complex handler.

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

If anyone has any comments, suggestions or recommendations please leave comment or let me know on twitter.


Fat Controller CQRS Diet: Simple Query

Simple QueryThis is a series of blog posts that demonstrate how to thin your controllers by implementing commands and queries using the MediatR library.  For demonstration, I’m converting the MusicStore application that’s using ASP.NET Core MVC.

For more information on the purpose of this series, check out my initial post.

Follow Along

You can get all the code for this entire series on on my fork of the MusicStore app GitHub.   If you have any improvements or suggestions, please create an issue or send a PR and I’ll be sure to include it in any of my blog posts.

Simple Query

For our first example, we are going to rewrite the HomeController Index action.  I figured it’s a the entry point into our app, so no better place to start.

What is also helpful in this example is it is fairly straight forward.  It contains some data access and in-memory caching prior to do view rendering.

Here’s what it looks like.

MediatR

There are a couple packages we need to add to our project.  We are going to be using MediatR as mentioned, however we are also going to add another package “MediatR.Extensions.Microsoft.DependencyInjection” by Jimmy Bogard (creator of MediatR).  This will scans assemblies and adds handlers implementations to the container.

Your project.json dependencies section should look as follows

Register MediatR

In our Startup.cs we need to register mediator in our ConfigureServices method.  The “MediatR.Extensions.Microsoft.DependencyInjection” added an extension method “AddMediatR” which we can now call to register all our handlers we will be created.

Add the following in the ConfigureServices method

Query Message

One of the ways I’ve explained Mediator pattern is like the post office (snail mail).  When you want to send a message to someone, you send it to the post office and they route it to the physical location for that message.  You don’t need to know how or where that location is, all you care about is giving it to the post office and let them do the work.

Instead of making a method call we are interchangeably going to create a message (object) and send it to the Mediator and have it figure how to create the appropriate handler and it dependencies and then invoke the handler.

Since our Home/Index method doesn’t require any parameters, our message is going to be pretty straight forward.

What we are doing is defining a class that implements IAsyncRequest.  The first type parameter defines the return value from our handler.  Meaning, when we send that message to the mediator what type do we expect in return.

Handler

Now we need to implement our handler.  Our handler will accept the the message (Home) and return a List<Album>.  What you will notice is I’ve for the most part taken the code from the controller and moved it to this handler.

Dependencies

One thing to notice is that our Handler’s constructor is taking dependencies (EF Context, Cache, AppSettings) that were originally defined in the Index method using dependency injection.

Thin Controller

Now let’s go back over to our HomeController and use MediatR.

First thing we will do is inject the IMediator into the HomeController via the constructor.  Then we will be calling MediatR with our Home message to get our list of albums.

Next

That’s a very simple query endpoint that we moved our logic to a Query Handler using MediatR.

Next up we we will handle a command.

If anyone has any comments, suggestions or recommendations please leave comment or let me know on twitter.