Sponsor: Do you build complex software systems? See how NServiceBus makes it easier to design, build, and manage software systems that use message queues to achieve loose coupling. Get started for free.
This 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:Simple Command
A command is request to change the state of our domain. The first controller action we are going to rewrite isShoppingCartController.AddToCart
Here is what the method originally looked like this.
As with our simple query, there are a couple things going on here.
- MVC is handling the albumId which is pass as an parameter to the method.
- We do some data access to get the album out of our EF DbContext
- Pass the album to our ShoppingCart
- Logging
- 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 theAlbumId
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 ourDbContext
and the ILogger
.
Thin Controller
Now we can jump back to our controller and create ourAddToCart
Request/Command and send to the Mediator, which will invoke our Handler.
Neat, I didn’t know about the “CancellationToken requestAborted” MVC feature!
Yes, and if you use MediatR, you can use the ICancellableAsyncRequestHandler and have your handler accept it. Thus, pass it thru to whatever else can use it like EF.
Pingback: Fat Controller CQRS Diet: Trade-offs - CodeOpinion
Pingback: Fat Controller CQRS Diet - CodeOpinion