Published: 03 Mar 2008
By: Oleg Zhukov
Download Sample Code

Learn how to develop .NET application with the help of the MVC# Framework.

Introduction

Architectural patterns such as Model-View-Controller are gaining more and more popularity nowadays. The reason is simple: they improve applications' design and raise their maintainability by splitting applications into three layers with distinct responsibilities. However incorporating such patterns into an application requires some effort - the fact that may discourage developers from using MVC and similar approaches. Fortunately a number of frameworks exist, which minimize the overhead of using architectural patterns such as MVC. One of such frameworks is MVC#. It assists developers in using the Model-View-Presenter pattern (an evolution of MVC) by taking on itself all routine work, allowing to develop 3-tier MVP applications with ease. 

In this article we will demonstrate how to build a Model-View-Presenter application with the help of the MVC# Framework. Our first example application will be intended for managing customers and their orders. It will consist of two views: the first one displays customers and has a button to switch to the second view. The second view lists orders for the selected customer and has buttons to operate on the order selected: "Accept", "Cancel" and "Ship". We will implement views both for Windows and Web presentation platforms, revealing how MVC# allows targeting the same application to different presentation mechanisms.

Before reading the article, be sure to get acquainted with the Model-View-Presenter essentials. A gentle introduction to MVP and MVC can be found here. Also note that the code listings throughout the article may omit minor details for simplicity sake. For exact code see the example sources.

Note: The source code of this example can be found under "Examples\Basics\" subfolder of the MVC# framework root folder. The framework itself can be downloaded from www.MVCSharp.org/download.aspx.

Figure 1: The sample application running

images/1.jpg

The Model

Firstly we are going to create the model part of the MVP triad. It will consist of two classes: Customer and Order. While the Customer class just holds a list of orders and a static list of all customers, the Order is a little more complicated having three operations.

Application Logic

Every MVC# application consists of one or more tasks. A task is an independent set of actions which accomplish some job, typically representing a use case for the system. Tasks may be "Book ticket", "Calculate taxes" and others. In our example application there will be a single task for managing customers and their orders. Each task consists of a number of views which a user traverses to complete the task. Our example task will have two views: "Customers" and "Orders".

In order to describe a task we should declare its class. For each view a public constant field, initialized with the view name, should be added to the task class. According to the Model-View-Presenter pattern a view is never alone, it always exists in pair with its controller (the view-controller pair is referred to as interaction point), that is why for each view we also specify its controller type with the [InteractionPoint] attribute.

Besides the controller type, the [InteractionPoint] attribute specifies permitted navigation targets. Thus above we have stated both Customers->Orders and Orders->Customers as possible transitions.

In MVC# all tasks should implement the ITask interface. Though this interface is rather simple and can be implemented manually, the MVC# framework already comes with a basic implementation called TaskBase. We will use it as a base for our MainTask class.

A part of the ITask interface is the OnStart operation. It should be implemented to define actions performed on task start. In our case we want the customers view to be activated when the task starts:

The NavigateDirectly method activates a view regardless of the current view (which is null at the beginning) and of possible navigation routes.

A task should be a container for global logic, used across the entire task and consumed by more than one controller. In our example such global meaning will have the currently selected customer. As we will see later it will be used by both controllers. That is why we will include a CurrentCustomer property to the MainTask. Moreover, the setter for this property will generate a CurrentCustomerChanged event:

Now we are ready to deal with the rest of the application logic placed in the controller classes. Let us start with the CustomersController class.

Customers Controller

Generally, controllers in the Model-View-Presenter paradigm handle the application flow: they process UI events using the Model tier classes when necessary, and decide what to display in the UI. The first thing the CustomersController class should do is configure the view with the customers list and the current customer. This should be done during the initialization phase when the controller is linked to its view:

Note that controllers in MVC# should conform to the IController interface. But as it is with the ITask interface MVC# provides a common IController implementation, ControllerBase, which we are using.

Next, CustomersController should process UI events. To be exact it should handle the "Show Orders" command from the UI and process the change of the customer currently selected in the customers form:

ICustomersView is the interface that the customers view should implement:

Orders Controller

The logic of displaying orders is quite simple: we should track the change of current customer and display its orders:

In the above code we first subscribe to the MainTask.CurrentCustomerChanged event as soon as the controller is linked to the task object. Then we just handle the customer change event by passing the corresponding orders to the view.

The next three methods represent the "Accept", "Ship", and "Cancel" operations on the currently selected order:

We might demand the view to disable certain operations depending on the current order state. For example one cannot ship an order before it is accepted. UpdateView is the method that analyzes the current order state and tells the view to enable/disable certain operations:

The OrdersController class should also have a CurrentOrderChanged operation for the view to notify the controller when a user clicks on another order:

Presentation

The presentation layer consists of view classes. All views in MVC# should implement the IView interface. In addition view classes should conform to particular interfaces dictated by the application logic layer. In our example such interfaces are ICustomersView and IOrdersView. Depending on the presentation platform chosen, view classes should inherit an appropriate base view class (either Windows form or Web form). We will design views for both platforms (Windows and Web) and will start with Windows form views.

First let us create the customers view for the Windows Forms presentation mechanism. As mentioned above it should be a subclass of the Windows Form class and should implement the IView interface. To reduce the amount of manual work we will make it inherit from the WinFormView class - a simple Form subclass implementing the IView interface.

Let us place a GridView component and a button on the form:

Figure 2: Designing the form

images/2.jpg

In order for the customers controller to talk to its view, the latter should implement the ICustomersView interface:

According to the MVP pattern, views receive the user actions and then pass control to the controller. In our case the customers view should handle the change of current customer in the grid and the "Show Orders" button click:

The last thing here is to point the MVC# framework that the above view class describes the "Customers" view in the MainTask task. This is done with the View attribute:

Similarly let us design the OrdersView form. It will contain a grid and three buttons:

Figure 3: Designing the OrdersView form

images/3.jpg

In the same manner as it was with the CustomersView, the OrdersView class should inherit from the WinFormView class and implement the IOrdersView interface for the framework and the controller to interact with it. It should also have a [View] attribute to indicate its belonging to the main task as the "Orders" view.

The following code shows how the OrdersForm handles user actions and delegates processing to the controller:

In Web environment the views design will be very similar to that in Windows. Views will inherit from the WebFormView class and will contain a grid and buttons on their surface:

Figure 4: Customers View

images/4.jpg

The ICustomersView implementation will be identical to that in Windows environment:

Button click and grid row selection event handler will look the same way too:

Here we do not list code for the orders Web form class as it is very similar to its Windows analogue above. If desired, a reader may look into the full sources of the example. Here is how the orders Web view looks in the designer surface:

Figure 5: Orders View

images/5.jpg

To associate the designed Web forms with the "Customers" and "Orders" views of the main task we use a slightly different technique (instead of [View] attributes): we add [WebformsView] attributes to a placeholder class inside the Global.asax file:

Starting the application

Every MVC# application requires some configuration steps. All configuration data is encapsulated in MVCConfiguration class instances. However instead of manually setting up MVCConfiguration objects it is possible to obtain preconfigured instances by the view managers' GetDefaultConfig() static method. After the configuration is done it is time to start the task by passing its type to the TasksManager.StartTask(...) method.

The code to configure and to start the main task looks similar in Windows and Web environments. The major difference is where to place that code. In Windows application we put it in the Main method, which is the entry point of a program:

In Web applications we place the main task start code in the session start handler in Global.asax file:

Summary

This example gives the general look on how to construct layered applications with MVC# framework. It demonstrates the common idea of the Model-View-Presenter approach - that is breaking an application into three layers: one for business objects (model), another for application logic (controllers), and the last for presentation (views). And it shows how MVC# simplifies implementing the MVP approach in your applications.

<<  Previous Article Continue reading and see our next or previous articles Next Article >>

About Oleg Zhukov

Oleg Zhukov, born and living in Russia is Lead Engineer and Project Manager in a company which provides business software solutions. He has graduated from Moscow Institute of Physics and Technology (MIPT) (department of system programming) and has got a M.S. degree in applied physics and mathematics...

This author has published 5 articles on DotNetSlackers. View other articles or the complete profile here.

Other articles in this category


Code First Approach using Entity Framework 4.1, Inversion of Control, Unity Framework, Repository and Unit of Work Patterns, and MVC3 Razor View
A detailed introduction about the code first approach using Entity Framework 4.1, Inversion of Contr...
Exception Handling and .Net (A practical approach)
Error Handling has always been crucial for an application in a number of ways. It may affect the exe...
jQuery Mobile ListView
In this article, we're going to look at what JQuery Mobile uses to represent lists, and how capable ...
Book Review: SignalR: Real-time Application Development
A book review of SignalR by Simone.
JQuery Mobile Widgets Overview
An overview of widgets in jQuery Mobile.

You might also be interested in the following related blog posts


Spec Explorer: A Model-Based Testing tool read more
12 ASP.NET MVC Best Practices read more
MvcContrib working on Portable Areas read more
RELEASED ASP.NET MVC 2 Preview 2 read more
5 Minute Overview of MVVM in Silverlight read more
Business Apps Example for Silverlight 3 RTM and .NET RIA Services July Update: Part 25: ViewModel read more
Default Templated Views read more
TechEd South Africa Slides and Code - .NET RIA Services and ViewModel read more
Who Activates, Displays, and Closes Screens? read more
ASP.NET MVC in Action at the Aggileland .Net Users Group tomorrow read more
Top
 
 
 

Discussion


Subject Author Date
placeholder source code Hassan Salman 11/18/2009 10:46 AM
RE: source code Oleg Zhukov 11/18/2009 6:11 PM
placeholder RE: source code Sonu Kapoor 11/18/2009 7:13 PM
Interesting, but I don't see much success Simone Busoli 3/5/2008 3:24 AM
placeholder RE: Interesting, but I don't see much success Oleg Zhukov 3/5/2008 5:06 AM
RE: RE: Interesting, but I don't see much success Thomas Tran 5/4/2008 8:57 PM
placeholder RE: RE: Interesting, but I don't see much success Simone Busoli 3/10/2008 7:42 PM

Please login to rate or to leave a comment.