Programming Microsoft ASP.NET 4 - Dino Esposito [324]
// Initialize the presenter (for Windows)
_presenter = new DefaultPresenter(this, new WinFormsQuoteServices());
}
...
}
Figure 15-8. Distinct applications share the same presenter.
Figure 15-7 and Figure 15-8 show two different versions of the same application—one for the Web and one for the desktop. As long as the presentation logic remains the same, and the dependency on the service layer can be managed, you can (and are encouraged to) reuse the same presenter class. Be aware, however, that this might not always be the case.
Note
If one of the potential clients is based on Silverlight, you should also consider that some of the features your code relies on might not be supported in Silverlight. In addition, Silverlight 4 has binary compatibility with .NET code, but the same isn’t true for earlier versions. Also, you are still unable to reference a .NET assembly from a Silverlight project; the opposite, though, works as long as there are no code incompatibilities.
Navigation
The presenter is also responsible for implementing navigation within the application. In particular, the presenter is responsible for enabling (or disabling) any subviews contained in the primary view and for selecting and reaching the next view.
The Application Controller Pattern
To handle navigation within views, MVP goes hand in hand with another pattern—Application Controller. The pattern defines a central console that holds all the logic to determine the next view and handle the screen navigation and the flow of an application. (See Figure 15-9.)
Figure 15-9. The application controller.
When it comes to implementation, you can proceed by creating a static class (say, you call it Navigator) that acts as the application’s front end for navigation. Here, the Navigator class is a plain container for the real navigation logic. You inject the application-specific navigation workflow through an additional component.
The extra layer represented by the navigation workflow shields the presenter from knowing the details of the platform specific navigation. For example, navigation within a Web Forms application is based on Response.Redirect, whereas navigation relies on form-based display in Windows Forms.
Defining the Navigation Workflow
Here’s a possible implementation of the interface that represents the navigation workflow. The interface includes a method to navigate directly to a given view and another to navigate from the current view to the next:
public interface INavigationWorkflow
{
void Goto(String view);
void NextViewFrom(String currentView);
}
The Navigator class wraps an object that implements this interface and exposes a façade to the presenter:
public static class Navigator
{
private static INavigationWorkflow _navigationWorkflow;
private static Object _navigationArgument;
public static void Attach(INavigationWorkflow workflow)
{
if (workflow != null)
_navigationWorkflow = workflow;
}
public static Object Argument
{
get { return _navigationArgument; }
}
public static void Goto(String view)
{
if (_navigationWorkflow != null)
_navigationWorkflow.Goto(view);
}
public static void Goto(String view, Object argument)
{
if (_navigationWorkflow != null)
{
_navigationArgument = argument;
Navigator.Goto(view);
}
}
public static void NextViewFrom(String currentView)
{
if (_navigationWorkflow != null)
_navigationWorkflow.NextViewFrom(currentView);
}
public static void NextViewFrom(String currentView, Object argument)
{
if (_navigationWorkflow != null)
{
_navigationArgument = argument;
Navigator.NextViewFrom(currentView, argument);
}
}
}
The Navigator class is a little more than just a wrapper for the interface. The class features an Argument property through which the presenter can specify data to be passed to the view. How navigation is implemented and how data is passed depends on the actual implementation of the navigation workflow.
Navigating Within a Web Forms Site
In Web Forms, navigation between pages can be achieved through a redirect.