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:
  1. Implementing a presenter class. The presenter should handle user events, update the model, and manipulate the state of the view.
  2. Implementing a view interface. The view interface should expose the view’s state elements.
  3. 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.
Model-View-PresenterQuickStartSolution.png
Figure 1
Model-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.
CompositeWebClientAutomation.png
Figure 2
The 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

Last edited Dec 5, 2007 at 11:30 AM by ejadib, version 2

Comments

sheir Feb 4, 2008 at 7:25 PM 
In my solution, when I go Tools->Guidance Package Manager, and enable Package; I see the following
Custom Web Client Factory Guidance Package October 2007
But when I say Ok to enable it, I get an error:

Microsoft.Practices.RecipeFramework.ActionExecutionException: An exception occurred during the binding of reference or execution of recipe BindingRecipe. Error was: Action EnableAjaxRef failed to execute:
Could not load type 'Microsoft.Practices.WebClientFactory.References.WebSiteProjectOrWebProjectAjaxInstalledReference' from assembly 'Microsoft.Practices.WebClientFactory.GuidancePackage, Version=1.0.2953.21496, Culture=neutral, PublicKeyToken=null'..
You can remove the reference to this recipe through the Guidance Package Manager.


What am I doing incorrectly?
Can someone provide step-by-step simply instructions so that I can get this working and be able to see the options as displayed on Figure 2 (ie Add User Control or Add Page or Add Master Page) .