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!