3 ways to spot if your controller is doing too much
June 22, 2016 · 4 minute read
"I've always heard that you should keep your controllers skinny"Someone on Reddit
It’s true, keeping your controllers thin is a good idea, but why?
Imagine you need to do some work in an ASP.NET MVC application you’re unfamiliar with? Now imagine all the business logic is right there in the controller actions.
Your job is to get a feel for the application, establish what’s already there and start working on a new feature.
What’s easier, to read through lots of “business logic heavy” controller actions and try to build up a picture of the application, or scan through thin controllers where the actions are limited to two or three lines?
Then you look at the tests and you find they all start by mocking out the HTTP context and session. If you want to test your new business logic, you’ll need to write a lot of boilerplate code just to get the controller tests working before you even get to your logic.
What if you decide to try out a different ORM or web framework like NancyFX? Are you going to have to take all of your business logic, copy it from the old controller and paste it into your new NancyFX solution?
It seems like thin controllers would help in all of the scenarios above.
Of course, no-one sets out to make fat controllers, even the biggest controllers started off small. But over time (and multiple developers) the controllers get bigger and bigger and bigger.
To turn this around and make your controllers thin again, you need to know how to spot that they’re getting too big. So how can you spot problem controllers?
Look at the number of usings
A clear sign of controller bloat is a long list of usings at the top of the file.
using AutoMapper;
using MVCExamples.Data;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Net.Mail;
using System.Web.Mvc;
using System.Data;
using System.Data.Entity;
using System.Net;
using System.Web;
using MVCExamples.Models;
The longer this list is, the more likely it is your controller has a lot of business logic in it.
If your aim is to keep the controllers thin, then the only references you’ll need are to the more “webby” implementation details such as System.Web
and System.Web.MVC
and to wherever your business logic resides.
Look at the number of injected services
Similarly, keep an eye on how many dependencies your controller takes. If you have to scroll horizontally to read them all there may be too many!
public OrderController(IMapper mapper, IEmailSender emailSender, IOrderService ordersService,
IOrderMapper orderMapper, ICustomerRepository customerRepository)
{
_mapper = mapper;
_emailSender = emailSender;
_orderService = orderService;
_orderMapper = orderMapper;
_customerRepository = customerRepository;
}
Bonus: If you remove these, you’ll probably get rid of a lot of those using statements as well.
Big methods
Sounds obvious, but the more code you find in a controller action, the more it’s doing and the more you have to read/understand when trying to get to grips with an application.
If your controller actions are more than three or four lines long, they may be doing too much.
It might help to remember the primary job of a controller, to handle parameters, delegate to business objects then format any results.
Quick fix
Once you’ve found your fat controller, you can quickly trim it down by by extracting the business logic into one service or by using something like MediatR which lets you raise a command and then write a separate handler to perform your business logic.
Beyond that you can try one of these approaches to slim it down even more.
In summary
Learn to spot controllers which are doing too much and you can take steps to whip them back into shape meaning you can continue to build features at the rate your users demand.
By keeping an eye on usings, dependencies and the length of your controller actions you can keep your controllers trim and focus on implementing your important business logic.