SubControllers are MVC Controllers that are also parameters to your action methods.  Incorporating their use in large systems allows for composition, dependency inversion, and separation of concerns.

Sometimes we want Controller actions to pass objects into SubControllers so that the SubControllers can do interesting things with them. 

For example, in a Product Controller we have the Product, and in a SubController we want to find a few Customers that have recently purchased that Product.  We don't want to call the Customer Repository in the Product Controller – instead we want to pass the Product to the SubController and let it handle talking to the Customer Repository.

It's easy to give the SubController a public property that the host Controller action can set.

public interface ISubController<T> : ISubController
{
    T Model { get; set; }
}

public abstract class SubController<T> : SubController, ISubController<T>
{
    public virtual T Model { get; set; }
}

To test this we need to be able to mock the RecentCustomersStubController so that we can assert that Model was set with the product object.

[Test]
public void Should_set_Model_property_of_SubController_with_product()
{
    var product = new Product();
    var subcontroller = MockRepository.GenerateMock<IRecentCustomersSubController>();
    var controller = new ProductController();

    controller.List(product, subcontroller);

    subcontroller.AssertWasCalled(s => s.Model = product);
}

To create a mock (with Rhino Mocks) we need to extract an interface from the SubController:

public class ProductController : Controller
{
    public ViewResult List(Product product, IRecentCustomersSubController recentCustomers)
    {
        recentCustomers.Model = product;
        return View();
    }
}

public interface IRecentCustomersSubController : ISubController<Product> { }

public class RecentCustomersSubController : SubController<Product>, IRecentCustomersSubController
{
    private readonly ICustomerRepository _customerRepository;

    public RecentCustomersSubController(ICustomerRepository customerRepository)
    {
        _customerRepository = customerRepository;
    }

    public ViewResult RecentCustomers()
    {
        Customer[] recentCustomers = _customerRepository.GetRecentCustomersOfProduct(Model);
        ViewData.Add(recentCustomers);
        return View();
    }
}