Fat Controller CQRS Diet: Trade-offs

Trade-OffsIn my Fat Controller CQRS Diet series, I’ve shown the mediator pattern and the MediatR library. After a recent discussion with Reid Evans, he made me realize I haven’t really described the trade-offs.  This post is going to focus on trade-offs and an alternative to using the mediator pattern.

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

  1. Overview of Series
  2. Simple Query
  3. Simple Command
  4. Command Pipeline
  5. Notifications
  6. Vertical Slices

Coupling

With the mediator pattern, communication between objects is encapsulated with a mediator object. Objects no longer communicate directly with each other, but instead communicate through the mediator. This reduces the dependencies between communicating objects, thereby lowering the coupling.

For me the purpose of using the mediator pattern is to limit the coupling between integration boundaries.  Those boundaries in my applications are typically the Web/UI Framework and my core application.

This means I’ll have my controllers take a dependency on the mediator and not my core application.

Runtime Resolution

The downside to this that there is no compile time type checking.  When the mediator is invoked at runtime, it could fail to send the request if there is no handler defined.

In the code example above, if there is no IAsyncRequestHandler<Home, List<Album>> then an exception will be thrown on _mediator.SendAsync(new Home());

Coupling to Handler (or Interface)

We could get around this and get our type checking at compile time by having the request handler injected into our controller.

This is fairly reasonable since I often have one controller per command or query.  This then limits the dependencies I’d be putting into the constructor.

Messaging

One aspect that I haven’t touched on (yet) in this series is about background processing and queues.  I really enjoy using Hangfire to create background jobs.   I’ve blogged about it before and how to integrate MediatR and Hangfire together.

The general approach I take is to use messaging between MediatR and Hangfire to keep it consistent on how commands or queries are made.  That means messaging with MediatR done in-process or done on out of process (on other machines) via Hangfire but routing them through MediatR.

Comments

GitHub

I love hearing your comments, questions and recommendations!  Please post a comments or on Twitter.


Side Projects: Validate Quickly or Learning Experience?

I periodically enjoy working on side projects.  Not just messing around, but a full blown side project that has some set of features that I think would be useful.

I never have any real intent of releasing them so I don’t ever put too much priority on them.

Usually what I take away from them are knowledge of new tools/frameworks/libs/patterns etc.  Althoguh they aren’t always completely new to me, they may just be deepening my current understanding.

For me these side projects go into three states:

  1. I get really into it and work on it non stop for a few weeks.
  2. Once I finally get over the fun parts and feel like I stopped learning, it ends up sitting quietly in a half working state.
  3. I abandon the project completely because I’ve thought of something else.
  4. Go to step 1

Product

I’ve recently had an idea for a project that I think would be a great product.

This is problematic to me because my side-projects have generally been a playground for learning new tech.

And if I wanted to create a product, I think I would be better off creating a prototype to validate the idea as quickly as possible so I don’t waste my time.

If I want to spend the least amount of time possible, I would use the languages and platforms that I know.

What do you do?

I’m curious if you the reader have a SaaS/Product idea, do you use the opportunity to learn new technology as well as validate the idea?

Killing two birds with one stone?

Or do you opt for using the tech you know and getting it done much quicker to validate your idea?

Love to hear from you in the comments below or on Twitter.


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.