Simplify your controllers with the Command Pattern and MediatR

June 6, 2016 · 3 minute read

So you want to keep your controllers thin even as your application becomes more and more complicated.

You’re concerned that your controllers are getting bloated and you’ve heard people talk about the command pattern as one possible solution.

But you don’t know how the command pattern would fit into your app. How many commands should you have? Do you need separate commands every time you want to change a field in your database?

Focus on features

One of the nice things about the command pattern is that you can pause thinking about your implementation, and focus on your user’s interactions.

Let’s say you are creating a site where users can register and log in. If you take these actions and turn them into commands you’ll end up with;

  • RegisterUser
  • LogIn

When you focus on creating commands like these, you can stay focused on the feature in question and defer all those niggling questions about service layers, fat controllers, where to put your code etc.

That’s not to say you shouldn’t consider the architecture of your app, but if you focus on the feature first, you can prove the feature works before getting bogged down with other (more technical) concerns.

Hello MediatR

The good news is, implementing the command pattern is simple, especially if you use Jimmy Bogard’s MediatR to send commands from your ASP.NET MVC/WebAPI controllers.

With MediatR you start by creating a simple C# class to represent your command.

public class RegisterUser : IRequest<bool>
    public string EmailAddress { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

The bool type parameter indicates the response type meaning in this case running this command will return a bool.

Then in your controller action you can “send” this command using MediatR.

public class UserController : Controller
    private readonly IMediator _mediator;

    public UserController(IMediator mediator)
        _mediator = mediator;

    public ActionResult Register(RegisterUser registerUser)
        bool registered = _mediator.Send(registerUser);
        return View();

Points to note

There’s a clean separation of concerns. You don’t need to pull repositories, services etc into your controller because all you need is the Mediator itself

Model Binding has automatically populated the command object (RegisterUser) based on the values passed in the HTTP request

This ensures your controllers stay bloat-free; focused entirely on handling requests and forwarding them on to your business logic.

So how do you actually handle this command? Simple, create a handler of course!

public class RegisterUserHandler : IRequestHandler<RegisterUser, bool>
        public bool Handle(RegisterUser message)
            // save to database
            return true;

And that’s it. You now have a simple controller action which sends the command and a handler to handle it.

Finally if you need multiple handlers to react to the same message you should take a look at MediatR notifications.

Join the Practical ASP.NET Newsletter

Ship better Blazor apps, faster. One practical tip every Tuesday.

I respect your email privacy. Unsubscribe with one click.