Model View Presenter
"Factor the UI into a view and controller where the view handles simple mapping to the underlying model and the controller handles input response and complex view logic."
Martin Fowler
Model View Presenter, or MVP for short is a presentation pattern which aids in structuring your system to allow for good separation of concerns between the presentation markup and the user interface flow logic.
On BackgroundMotion we used the MVP pattern by extending the prescribed approach in the Composite Web Block to structure our code to promote testability and good separation of concerns.
Andrew describes how we used the Model View Presenter pattern
How it works
MVP is implemented by creating a Domain Model, a number of Views and a number of Presenters. In BackgroundMotion our Domain Model is represented in the Model project, the Views are the ASP.NET .aspx pages, the Presenters are classes living in the Mindscape.BackgroundMotion.Website.Views namespace.
Lifecycle of a Request
To help understand further, let's look at what happens when a request to fetch a contribution on the View.aspx page is executed.
Step 1:
A web request is processed against View.aspx as per normal
Step 2:
The Presenter will respond to the OnLoad event for the Page. This has been wired up through the PageBase class.
if (!IsPostBack)
{
_presenter.OnViewInitialized();
}
_presenter.OnViewLoaded();
}
The Presenter wires up and responds to the OnLoad event
Step 3:
Our Views have strongly defined interfaces. This is one of the requirements of an MVP implementation that helps achieve loose coupling between a View and a Presenter.
We now have the flexibility to later choose to use a different View as long as it implements the required interface, or multiple Presenters could use the original View.
In the Mindscape.BackgroundMotion.Website.Views.IViewView interface we define this contract:
public interface IViewView : IView
{
/// <summary>
/// The contribution which has been requested
/// </summary>
Contribution Contribution { get; set; }
Notice how the view expects to be assigned a Contribution object from our domain model which will scope what it will render out.
The Presenter loads the required Model and populates the View
The Presenter assigns the Contribution we asked for by assigning a value to the .Contribution property on the View.
Contribution contribution;
if (null != (contribution = Controller.ViewContribution(id.Value)))
{
View.Preview = ParsePreviewLink(contribution);
View.Contribution = contribution;
}
else
{
Controller.RedirectTo("~");
}
Resources