Fat Controller CQRS Diet: Vertical Slices

This 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.  Specifically in this post, I’ll look at organizing your code by vertical slices.

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
  5. Notifications

Organize by Feature

Feature Slices or Vertical Slices are the terms I’ve heard the most for what I call Organize by Feature.

I’ve just always characterized as organizing all relevant code and files from a command or query into a specific folder or hopefully single file.

I generally stay away from creating layers so the term Vertical Slices does make a lot of sense.

Whatever our feature slice is, it surely makes sense to keep all that code together.

Single File

If you’ve seen the code related to my Command Pipeline or Notifications posts, then you should already be able to tell where I’m heading in terms of organization.

I generally like to keep the command/query and it’s associated handler all within the same file.  In the case of our logging handler, I was also keeping it in this file.

Pretty simple.  One file for everything related to a command or query.

Controllers & Views

Well almost.  What I hadn’t really moved were the controllers or views.  So let’s do that now.

Controllers are pretty easy since by default they can live anywhere within your project. ASP.NET MVC Core will just pick them up.

Let’s work on our Home Query.  We will simply create a HomeController within our Home.cs file that currently contains our query and our handler.

Because we are no longer using the default routing, I’ve added the HttpGet attribute to the method to keep the route intact to what it was prior.

View Locator

By default, ASP.NET Core MVC will look in the ~/Views/ folder with default conventions.  But we want to put our view right along side our Home.cs file in our Features folder.

So I’ve moved all of the view files into our Features folder.  Our solution now looks like this:

 

In order to tell ASP.NET where our views are now at, we can implement the IViewLocationExpander

Now in the  IServiceProvider ConfigureServices(IServiceCollection services) method from our Startup.cs, we can can configure to use our new locator.

That’s it!

We now have one file that contains our controller, query and handler.  And right along side it we have our associated view.

Comments

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

I love hearing your comments, questions and recommendations as it usually leads me down to other blog posts.  Please post a comments or on Twitter.


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.


Running a .NET User Group

Running a .NET User GroupBack in June 2016, I posted about my experience starting a User Group.   It covered some of the basics of the very initial forming of the group and various feedback.  Since it’s now been half a year and we’ve had 6 meetups since then, I figured it was time for a post about how it’s been running a .NET User group.

Speakers

Originally thought the toughest part of running the user group would be getting speakers.  However, this early on in the life of the user group, it hasn’t been much of an issue.

I think there is one main reason for this.

I already had a pool of people in mind to do talks from the very beginning of starting the group.  As each meetup goes by, my pool shrinks.  At some point this will become a concern.

Attendance

This is the most challenging part of running my user group.  I want it to be well attended and grow.  It’s very early still and we have new faces show up each month, which is great.

My main way of reaching people is standard word of mouth and various social networking announcements.  This will change.

Facility

I was recently at a conference and met up with Ken Cenerelli and Tom Walker.  One suggestion I was given by Tom, was that he periodically holds their meetups at a sponsoring company location.

I think this is a very interesting idea because then at least makes that sponsoring company’s developers aware of the meetup, which they may or may not of known about prior or of attended.

I plan on trying this out in the new year and seeing if there are some positive results.

Sponsors

People love free stuff.  And it’s even better when it’s useful.  I’ve been lucky to get a few early sponsors which have been great.

Microsoft Technical Communities is a great way to submit your event to be posted on their site as well as request food sponsorship for your event.

Telerik has sponsored us with swag and software licenses to give away each month.  They were really great in sending me a box of swag right after my email request for sponsorship.

DevExpress just recently provide us with CodeRush for Roslyn license to give away each month.  I received their notification of sponsorship while we were hosting our November meetup which was perfect timing!

Networking

While I was talking with Ken and Tom, we discussed how the content that the user group provides isn’t really the what the user group’s biggest benefit is.

There is so much content and ways to learn online, there really isn’t any need to go to a user group with the primary goal to learn.

The main reason is for going to a user group is networking.  To make new connections and strengthen existing ones.

Comments

If have you run a user group and have suggestions I’d love to hear from you. Please leave comment or let me know on twitter.