In order to keep my fat controllers thin I ensure that they are only concerned with a single responsibility, i.e. handling the coordination of my UI logic. To achieve this my controller delegates to other classes to actually perform tasks and retrieve data. However, even though I can keep my ActionResult methods thin and highly cohesive I can still end up with a very tall controller that is handling the coordination of too much UI logic. Let me show you what I mean.
I often see controllers like the class below:
public class CustomerController : Controller
{
public ActionResult Details()
{
//....
}
public ActionResult Edit()
{
//....
}
[HttpPost]
public ActionResult Edit(EditCustomerViewModel edit_customer_view_model)
{
//....
}
public ActionResult AddDeliveryAddress()
{
//....
}
[HttpPost]
public ActionResult AddDeliveryAddress(AddCustomerAddressViewModel add_customer_address_view_model)
{
//....
}
public ActionResult EditDeliveryAddress()
{
//....
}
[HttpPost]
public ActionResult EditDeliveryAddress(EditCustomerAddressViewModel edit_customer_address_view_model)
{
//....
}
}
This controller is concerned with everything to do with managing a customer, and even though it may have thin and cohesive ActionResult methods it can quickly become large and difficult to work with as it is handling too many UI tasks.
A better way I have found to tackle this issue is to create a controller class per business UI task or concern. So in the case of the tall controller shown above I would instead split this into multiple controllers, having one for editing a customer, one for displaying a customer and so on as shown in the following listing.
The CustomerDisplayController class is concerned with UI tasks to display a customer.
public class CustomerDisplayController : Controller
{
public ActionResult Details()
{
//....
}
}
The CustomerEditController class is concerned with UI tasks to edit a customer.
public class CustomerEditController : Controller
{
public ActionResult Edit()
{
//....
}
[HttpPost]
public ActionResult Edit(EditCustomerViewModel edit_customer_view_model)
{
//....
}
}
The AddDeliveryAddressController class is concerned with UI tasks that add an address for a customer.
public class AddDeliveryAddressController : Controller
{
public ActionResult AddDeliveryAddress()
{
//....
}
[HttpPost]
public ActionResult AddDeliveryAddress(AddCustomerAddressViewModel add_customer_address_view_model)
{
//....
}
}
The EditDeliveryAddressController class is concerned with UI tasks that edit a customers address.
public class EditDeliveryAddressController : Controller
{
public ActionResult EditDeliveryAddress()
{
//....
}
[HttpPost]
public ActionResult EditDeliveryAddress(EditCustomerAddressViewModel edit_customer_address_view_model)
{
//....
}
}
You probably figured this out for yourself but I thought I may as well jot it down for future reference :0)
Keep on rockin
Scott