Total votes: 0
Print: Print Article
Please login to rate or to leave a comment.
Published: 03 Mar 2008
Download Sample Code
Learn how to develop .NET application with the help of the MVC# Framework.
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.
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
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.
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
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:
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
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.
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:
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:
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
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
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
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
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
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:
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.
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.
Please login to rate or to leave a comment.