Model-View-Presenter pattern description |
How to: Unit Test the Presenter |
Model-View-Presenter QuickStarts
How to: Implement the Model-View-Presenter Pattern
The typical implementation process of the Model-View-Presenter pattern includes the following tasks:
- Implementing a presenter class. The presenter should handle user events, update the model, and manipulate the state of the view.
- Implementing a view interface. The view interface should expose the view’s state elements.
- Implementing a view class. The view contains user interface artifacts. The view should forward user events to the presenter and expose properties for the presenter to manipulate the view’s state.
Implementing a Presenter Class
The presenter should handle user events, update the model, and manipulate the state of the view. Usually, the presenter is implemented using Test Driven Development (TDD). Starting with the presenter, implementation lets you focus on business requirements and application functionality independently of the interface implementation details.
When implementing the presenter, you will need to create a simple view and model objects to be able to express the interaction between those and the presenter. To be able to test the presenter in isolation, make the presenter reference the view interface instead of the view concrete implementation. By doing this, you can easily replace the view with a mock implementation when writing and running tests. A similar approach can be followed for model artifacts.
Interaction with the View
The communication with the view is usually accomplished by setting and querying properties in the view to set and get the view’s state, respectively. For example, a view could expose a
Customer property for the presenter to set the customer that the view should display. Another valid approach consists of invoking methods on the view. For example, the presenter could invoke a method named
ShowCustomer(Customer) to indicate to the view that it has to show a customer.
For example implementations of presenter classes, see the
ContactDetailPresenter and
ContactsListPresenter classes in the Model-View-Presenter QuickStart. These classes are located in the Views folder of the Contacts project.
Testing the Presenter
For details about how to test the presenter, see
How to: Unit Test the Presenter.
Implementing a View Interface
The view interface should expose the view’s state. Typically, a view interface contains properties for the presenter to set and query the view’s state. Exposing properties over methods in the view usually keeps the presenter simpler because it does not need to know about view implementation details, such as when data is to be bound to user interface controls.
Depending on how the view interacts with the presenter, the view interface might also have additional elements. If the view interacts with the presenter by raising events, the view interface will include event declarations.
The following code extracted from the Model-View-Presenter QuickStart illustrates a view interface definition.
public interface IContactDetailView
{
void LoadStates(ICollection<State> states);
void SetViewReadOnlyMode(bool readOnly);
void SetViewControlsVisible(bool visible);
void ShowCustomer(Customer customer);
ContactDetailPresenter Presenter { get;}
event EventHandler EditClicked;
event EventHandler<DataEventArgs<Customer>> SaveClicked;
event EventHandler DiscardChangesClicked;
event EventHandler UserControlLoaded;
}
Implementing a View Class
The view (a Web page, a user control, or a master page) contains user interface elements. The view should forward user events to the presenter and expose properties or methods for the presenter to manipulate the view’s state.
If you are using the Supervising Controller variant, the view should also perform direct data binding to the model (for example, using the ASP.NET built-in
ObjectDataSource control). In cases where the presenter exclusively handles the interaction with the model, the
ObjectContainerDataSource control included in the
Composite Web Client Library will help you implement data binding through the presenter. The
ObjectContainerDataSource control was designed to facilitate data binding in a Model-View-Presenter scenario, where the view does not have direct interaction with the model.
Interacting with the Presenter
The communication with the presenter—to forward user gestures—can be achieved in different ways. One approach consists of directly invoking methods in the presenter; this approach requires you to implement additional methods in the presenter and couples the view with a particular presenter. Another approach consists of having the view raise events as user events occur. This approach requires code in the view to raise events and code in the presenter to subscribe to the view events and results in reduced coupling between the view and the presenter.
For example implementations of view classes, see the
ContactDetail and
ContactsList classes in the Model-View-Presenter QuickStart. These classes are located in the Contacts folder of the MVPQuickStart Web application project.
Solution Structure
Typically, you store presenter classes and view interfaces in a class library project and view implementations (Web pages, user controls, or master pages) in a Web site or Web application project.
Figure 1 shows the Model-View-Presenter QuickStart solution.
Figure 1Model-View-Presenter QuickStart solution.
Using Automation to Implement the Model-View-Presenter Pattern
The
Composite Web Client Automation adds automation to Visual Studio for developers to easily perform common development tasks. The
Composite Web Client Automation includes three recipes (automated tasks) that you can execute to implement the Model-View-Presenter Pattern in a Composite Web client solution:
- Add Page (with presenter) recipe. This helps you to add a new view class and the associated presenter class to an existing business module. It adds the class files that implement the Web page, an interface for the page, and the corresponding presenter.
- Add Master Page (with presenter) recipe. This helps you to add a new master page and the associated presenter class to an existing business module. It adds the class files that implement the master page, an interface for the master page, and the corresponding presenter.
- Add User Control (with presenter) recipe. This helps you to add a new user control and the associated presenter class to an existing business module. It adds the class files that implement the user control, an interface for the user control, and the corresponding presenter.
Figure 2 shows the
Web Client Factory shortcut menu that appears when you right-click a folder in a Web site.
Figure 2The Composite Web Client Automation automates common development tasks.For information, including download information, see
Composite Web Client Automation on CodePlex.
Model-View-Presenter pattern description |
How to: Unit Test the Presenter |
Model-View-Presenter QuickStarts