Share on reddit
[`google_buzz` not found]
Bookmark this on Digg
Share on StumbleUpon

INFO: If you are looking for information specifically related to ASP.Net MVC, then continue your Google Search.  This article is about the MVC Design Pattern and a simple implementation in C#.

OVERVIEW: The MVC (Model-View-Controller) design pattern was introduced by the Gang of Four as a means of describing an application from the perspective of the three layers of the application (Data – Presentation – Logic).  Over the years many different implementations of the MVC pattern have emerged.  I am now about to introduce my personal implementation which has served me well for nearly a decade.

THE MODEL:  Since this is a .Net blog, I will give my example using Microsoft’s Entity Framework.  Whether you prefer to design on the database or in code, the DbContext you create is the perfect repository for your data.  As a matter of fact, the objects created by the DbContext are perfect for your Models, so you don’t have to write any special code!

THE VIEW:  Many MVC implementations lock the view into a specific technology.  I do not.  Instead, I expose Views as Interfaces.  What implements the interface is irrelevant. Here is an example View:

public interface IView
{
    // This is the interface that all views will derive from. This
    // base view will allow us to generalize the controller.
}

public interface ISampleView : IView
{
    // Properties representing your data
    List<Model%gt; ModelData { get; set; }

    // Actions that the controller responds to
    event EventHandler<Model> SaveModelData;
    event EventHandler<Guid> LoadModelDataByGroupUID;

    // Actions that the view responds to
    void BindModelData();
}

Now that we have defined our view, we can implemented it in many different ways. Here’s a simple Web Form that implements the above view.

public class SampleView : Page
{
    public List<Model> ModelData { get; set; }

    public void BindModelData()
    {
        // Assume the ASPX file defines a ListView named ListView1
        // and we want to sort on a specific field before displaying
        // The data.
        ListView1.DataSource = ModelData.OrderBy(x => x.SortField).ToList();
        ListView1.DataBind();
    }
    
    public event EventHandler<Model> SaveModelData;
    public event EventHandler<Guid> LoadModelDataByGroupUID;
}

The view doesn’t have a lot of moving parts (as is correct). The only real work done in the view is shaping the data for presentation. The main work is handled in the Controller.

THE CONTROLLER: Now we’re talking about the main part of the application. This is where the real work is done. Controllers are typically plain old classes that register a view and manage the interaction between the needs of the view and the storage and manipulation of the data. Often the Controller is a stand alone class, but some frameworks provide an abstract class that provides reusable features. I will instead provide a IController interface to provide a simple Initialize method.

public interface IController
{
    Initialize(IView view);
}

Pretty simple, but this ensures that the View implementation has a consistent contract for registering itself with the controller.

Now, let’s take our example and actually load and save the Model from our SampleView.

public class SampleController : IController
{
    private IView _view;
    protected ISampleView SampleView { get { return _view as ISampleView; } }

    public Initialize(IView view)
    {
        _view = view;
        if(SampleView != null)
        {
            SampleView.SaveModelData += SampleViewSaveModelData;
            SampleView.LoadModelDataByGroupUID += SampleViewLoadModelDataByGroupUID;
        }
    }

    protected void SampleViewSaveModelData(object sender, Model data)
    {
        if(SampleView != null)
        {
            using(var context = new SampleDbContext)
            {
                var existing = context.Models.FirstOrDefault(data);
                if(existing != null)
                {
                    // Copy fields from data to existing
                }
                else
                {
                    context.Models.Add(data);
                }

                context.SaveChanges();
            } 
        }
    }

    protected void SampleViewLoadModelDataByGroupUID(object sender, Guid key)
    {
        if(SampleView != null)
        {
            using(var context = new SampleDbContext)
            {
                SampleView.ModelData = context.Models.Where(x => x.GroupUID = key).ToList();
                SampleView.BindModelData();
            }
        }
    }
}

CONCLUSION: The MVC pattern allows for complete abstraction of the data, presentation and manipulation of that data. Here I’ve provided an overly simplistic example of a complete MVC example. I would strongly encourage you to take this example and expand upon it. For example, you can add fields to your View and then incorporate them into the logic of your controller. The sky is the limit!