Implementing the MVC Design Pattern in ASP.NET
page 5 of 7
by Joydip Kanjilal
Feedback
Average Rating: 
Views (Total / Last 10 Days): 49494/ 59

Implementing a Sample Application

In this section we will design and implement a sample application that makes use of the MVC Design Pattern. Before we delve further, let us take a quick look at the class diagram to understand the classes and the interfaces in the design and how they are related to each other.

Figure 2: The Class Diagram

Here is the list of the interfaces that we will be using in our application.

·         IDataModel: This is the interface that will be implemented by all our data model classes.

·         IView: This is the interface that will be implemented by all views that we design using this architecture.

·         IController: This is the interface which will be implemented by the ControllerBase class.

·         IBusinessEntity: This is the base interface for all business entities.

Listing 1: The IBusinessEntity interface

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
 
public interface IBusinessEntity
{
    Object Key
    {
        get;
        set;
    }
}

Note that the IBusinessEntity interface contains only one property, Key, that contains a unique value that identifies each business entity.

Listing 2: The IDataModel interface

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
 
public interface IDataModel
{
    void Create();
    void Update();
    ArrayList Read();
    void Delete();
    ArrayList Data { get; }
 
    int RecordCount
    {
        get;
    }
}

As you can see, the IDataModel contains the CRUD (Create, Read, Update and Delete) method definitions and two properties that relate to the data that the model holds and the count of the records in the model.

Listing 3: The IView interface

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
 
public interface IView
{
  void Notify(String strMessage);
  void InvalidateView();
}

The IView interface shown above contains two method definitions, the Notify(String strMessage) and the InvalidateView() method. While the former is used to notify the view of any event, the later is used to refresh the contents of the view with the latest data from the model.

Listing 4: The IController interface

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
public interface IController
{
    void Create();
    void Update();
    void Delete(Object objID);
    void Read();
    IDataModel DataModel
    { get; set; }
    IView View
    { get; set; }
}

The IController interface contains the CRUD method definitions and it holds the references to the view and the model. The ControllerBase class, shown next, implements this interface.

Listing 5: The ControllerBase class

using System;
using System.Collections;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;

 

public class ControllerBase : IController
{
    public IView iView;
    public IDataModel iDataModel;
 
    public ControllerBase(IView iView)
    {
        this.iView = iView;
    }
 
    void IController.Create()
    {
        this.iDataModel.Create();
    }
 
    void IController.Update()
    {     
    }
 
    void IController.Read()
    {
        this.iDataModel.Read();
        iView.InvalidateView();
        iView.Notify("Total number of records: " + 
            this.iDataModel.RecordCount.ToString()); 
    }
 
    void IController.Delete(Object objID)
    {     
    }
    public IView View
    {
        get
        {
            return iView;
        }
 
        set
        {
            iView = value;
        }
    }
 
    public IDataModel DataModel 
    { 
        get 
        {
            return this.iDataModel;
        }
 
        set 
        {
            this.iDataModel = value; 
        } 
    }
}

Next, we will take a look at the BaseDataModel class that implements the IDataModel interface shown earlier.

Listing 6: The BaseDataModel class

using System.Collections;
using System.Collections.Generic;
 
public class BaseDataModel : IDataModel
{
    protected ArrayList dataList = new ArrayList();
 
    ArrayList IDataModel.Read()
    {
        return dataList;
    }
 
    ArrayList IDataModel.Data
    {
        get
        {
            return dataList;
        }
    }
 
    void IDataModel.Create()
    {
 
    }
 
    void IDataModel.Update()
    {
 
    }
 
    void IDataModel.Delete()
    {
 
    }
 
    public void AddData(IBusinessEntity obj)
    {
        dataList.Add(obj);
    }
 
    public void RemoveData(IBusinessEntity obj)
    {
        dataList.Remove(obj);
    }
 
    public void Refresh()
    {
        dataList.Clear();
    }
 
    int IDataModel.RecordCount
    {
        get
        {
            return this.dataList.Count;
        }
    }
}

The EmployeeDataModel class extends the above class and implements the same interface; it extends that BaseDataModel class and implements the IDataModel interface.

Listing 7: The EmployeeDataModel class

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
 
public class EmployeeDataModel : BaseDataModel, IDataModel
{
    void IDataModel.Create()
    {
        IBusinessEntity employee = new Employee();
        ((Employee)(IBusinessEntity)employee).Key = "E2008-0001";
        ((Employee)(IBusinessEntity)employee).Name = "Joydip Kanjilal";
        this.AddData(employee);
        employee = (IBusinessEntity)new Employee();
        ((Employee)(IBusinessEntity)employee).Key = "E2008-0002";
        ((Employee)(IBusinessEntity)employee).Name = "Anand Narayaswamy";
        this.AddData(employee);
        employee = (IBusinessEntity)new Employee();
        ((Employee)(IBusinessEntity)employee).Key = "E2008-0003";
        ((Employee)(IBusinessEntity)employee).Name = "Steve Smith";
        this.AddData(employee);
        employee = (IBusinessEntity)new Employee();
        ((Employee)(IBusinessEntity)employee).Key = "E2008-0004";
        ((Employee)(IBusinessEntity)employee).Name = "Michelle Smith";
        this.AddData(employee);
    }
}

And then we have our employee business entity class called EmployeeDO. It implements the IBusinessEntity class shown earlier. Here is the code.

Listing 8: The EmployeeDO class

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
 
public class Employee : IBusinessEntity
{
    private String employeeName;
    private Object key;
 
    public Object Key
    {
        get
        {
            return this.key;
        }
 
        set
        {
            this.key = value;
        }
    }
 
    public String Name
    {
        get
        {
            return this.employeeName;
        }
 
        set
        {
            this.employeeName = value;
        }
    }
}

Note that we will make use of an Object Factory class to instantiate classes. I will show you how we will use this class later; let us take a quick look at the code.

Listing 9: The Generic Object Factory

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
 
public static class ObjectFactory
{
    public static T CreateObject<T>()
    {
        return Activator.CreateInstance<T>();
    }
}

This class is based on generics and contains one static method called CreateObject that accepts a generic type, instantiates the type and the returns the instance to the caller. Here is how we will make use of this class in our application.

Listing 10: Using the Generic Object Factory

IController iController.DataModel = (EmployeeDataModel)
ObjectFactory.CreateObject<EmployeeDataModel>();

Note that you require the necessary cast to assign the returned instance to the appropriate type. This is because the return type of the CreateObject() method is a generic type. Lastly, we will take a look at the presentation layer, i.e., the view that invokes the controller which in turn invokes the other layers to display data in the presentation layer.

We will take a simple view that will contain a repeater control that we will use to display the data (from the model) returned by the controller to it. Here is the markup code.

Listing 11: The Markup code of the View

<form id="form1" runat="server">
    <div>
        <asp:Repeater ID="Repeater1" runat="server">
    <HeaderTemplate>
        <table border="1">
            
           <th>
               <asp:Label id="lblPatientCode" Text="Employee Code" runat="server" />
            </th>
            <th>
               <asp:Label id="lblPatientName" Text="Employee Name" runat="server" />
            </th>
             
    </HeaderTemplate>
    <ItemTemplate>
    <tr>
            <td>
                <%# DataBinder.Eval(Container.DataItem, "Key")%>
            </td>            
 
            <td>
                <%# DataBinder.Eval(Container.DataItem, "Name")%>
            </td>            
        </tr>
    </ItemTemplate>
</asp:Repeater>
    </div>
    <div>
    <asp:Label id="lblMessage" Text="" runat="server" />
    </div>
    </form>

Note that the Label control called lblMessage will be used to display any notification message in the view. Here is the complete code behind source code for our view.

 

Listing 12: The complete source of the view

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;
 
public partial class _Default : System.Web.UI.Page,IView 
{
    private IController iController;
 
    protected void Page_Load(object sender, EventArgs e)
    {
        iController = new ControllerBase(this);
        iController.DataModel = (EmployeeDataModel)
            ObjectFactory.CreateObject<EmployeeDataModel>();
        iController.Create();
        iController.Read();
    }
 
    void IView.InvalidateView()
    {        
        Repeater1.DataSource = iController.DataModel.Data;
        Repeater1.DataBind();
    }
 
    void IView.Notify(String message)
    {
        lblMessage.Text = message;
    }
}

When we execute the application, the output is similar to what is shown in the figure below.

Figure 3

Note that the employee records are displayed using the repeater control. The message "Total number of records: 4" is displayed as a notification message. We will now understand how the program works.

In the presentation layer, we instantiate the ControllerBase class and pass the reference of the view to it using the constructor. Then the generic Object factory is used to create an instance of the data model and assign this reference to the DataModel property of the ControllerBase instance just created. In our example, the data model is the EmployeeDataModel class. Next, the Create() method is called on the ControllerBase instance we created earlier. This method in turn calls the Create() method of the EmployeeDataModel that creates a set of records of the Employee business entity and stores these records in an ArrayList instance. Now, we make a call to the Read() method on the ControllerBase instance which in turn calls the Read() method of the data model to retrieve the records we just created. The Read() method of the ControllerBase class then invalidates the view which binds the data retrieved to a repeater control. We are done!


View Entire Article

User Comments

No comments posted yet.

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-19 6:34:33 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search