7.1. Problem

Our controllers so far have parameterized constructors that expect some interfaces. For example, our AccountController expects an IFormsAuthentication and a MembershipProvider, and our MessageController expects an IMessageService. Currently our MessageController class has two constructors:

public MessageController()
    : this(null)
{
}
public MessageController(IMessageService service)
{
    Service = service ?? new InMemoryMessageService();
}

The default constructor is called by the MVC framework, which, in turn, calls the parameterized constructor with null values. The parameterized constructor instantiates an implementation of the interface if the passed value is null. This works well and allows us to use the parameterized constructor without changing the framework's instantiation process. The problem with this pattern is that our code is tightly coupled to a specific implementation of the interface — specifically, the InMemoryMessageService implementation. Remember that we used interfaces because they simplify testing and mocking, as well as enable us to plug in different implementations throughout the life of the application. If we wanted to use a different implementation — say, SqlMessageService — we would have to recompile and redeploy the application. That is not an acceptable price to pay and defeats the plugability enabled by the use of interfaces.

Get ASP.NET MVC 1.0 Test Driven Development: Problem - Design - Solution now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.