Using MVP with ASP.Net Web FormsHere I am going to give a quick example of using MVP with Asp.Net Web Forms. Although I have a development history of Web forms and MVC, I have favoured MVC in the past few years mainly because it helps seperate out the application layers and allows the easier inclusion of unit testing. However my current client has a large collection of ASP.Net Web Forms applications and they have no intention of moving over to MVC. They are interested in unit testing and dependency injection frameworks, so utilising the MVP pattern with web forms was the best path to take.
MVC & MVPThe main difference between MVC and MVP is how views are handled. In MVC it is down to the controller to choose which view is to be sent to the client whereas in MVP there is no real choice the view is managed by a presenter.
Basics of MVP
There are two varients of MVP; Passive View and Supervising Controller. I am going to concentrate on Passive View for this article as that is what I have more experience with and I believe it allows the easier adoption of unit testing although you do end up with a larger solution. Like more traditional ASP.Net Web Forms applications, you have a main solution with web project within it. But here the web project is a pretty dumb project in regards to business logic. For this example the web project is the View. There can be any number of other projects in the solution, but the main ones are Model (class library), Presenter (class library) and Tests (class library). It is also acceptable to have a Service project and ViewModel project; but I will not touch on those here. The key aspect of communication between the View and Presenter is the use of Interfaces. In this example I am going to create a simple login page which on successfull login redirects the user to a secure home page and on failure kicks them back to an error page. Quite simple. The code behind of an aspx page implements an interface which exists in the Presenter project. This interface exposes properties on the aspx page like this:- ILoginView.csLogin.aspxLine 14: Creates an new instance of the presenter which knows about the ILoginView and IAuthorizationService interfaces (don't worry about the authorization service, it sits in the service project). Line 19: The CheckUser method is called which in turn calls the LookupUser method in the authorization service class. This is where the interaction between Presenter and Model occurs; in practice this service would be separated in to the Service project. For this to work, we need to be using an IoC (Inversion of Control)/DI(Dependency Injection) framework. I have opted to use Castle.Windsor for this. I won't delve into this code too much except to say it basically injects an instance of AuthorizationService whenever it finds IAuthorizationService. This is done via the BasePage class which is inherited by the aspx code behind class. LoginPresenter.csLine 18: If it is a valid user, the properties for the View are set on lines 23 and 29. Back to Login.aspx line 21: Now the FileName property has been set, the redirect takes the user there. As you can see there is not much going on in the View; all the logic is left to the Presenter layer to look-up the user. This separation allows the inclusion of dependency injection (a later post) and unit testing.