Tuesday, September 4, 2012

MVC, MVP, ASP.NET

MVC design pattern in comparison with MVP on ASP.NET platform

ASP.NET MVC among others, has two main pillars:
1) Routing – which handles all requests as the direct calls to the controllers’ actions (http://MyServer/Person.mvc/List/ does not navigate to default file in the directory Person.mvc/List/ - but is transferred to call of the Action “List” on the controller “Person”) and
2) Views and pages almost do not have life-cycle events, because there is no need for them – everything was already handled by controller, very very before the View even came into play.

Web-Forms, .aspx Pages

Web-Forms (.aspx pages with just one FORM tag on the page with runat=’server’ attribute) where introduced in the very beginning of the .NET (1.0). This concept came in the times of VB script .asp pages (if talking only about MS world). Web-Forms were presented as the totally different approach with page handlers, which were firing dozens of events (PreInit, Init, PreLoad, Load…). These events were suggested as the right place for calls to business logic (Business rules, Data access etc.). Why? Because these events were the center point of your application.
In contrast with VB script (.asp pages) this architecture was tremendous change. It was jump from in-line html wraped in VB Script into real OOP world provided by .NET C# (still top product). OK, it sounds really good.
But surprisingly: everyone (developer) sooner or later started to tweak this functionality, something was not correct. Viewstate started to be deadweight, as well as the over any limit growing Sessions. Life-cycle event-set was soon revealed as ‘easy-to-remember’ as the names of all US states. But there were these features (and many others) and it was confusing to use them accurately.  
The .NET evolved and the .NET 4.0 is almost knocking on the door. But Web-Forms are almost the same. To use Web-Forms as they are is not so easy on larger projects. Therefore many communities were established with one purpose - provide some extensions which could make ASP.NET development easier. Microsoft decided to support community injecting the MVP design pattern into the .aspx world, and started to call it best practices.

Web-Forms improvements based on MVP, WCSF

Some of open source communities, which started improving the Web-Forms, did bet on the MVP design pattern. Good and working example is WCSF. In some sources you can find typical idea: MVP has evolved from the MVC. But what is really MVP and how differs from MVC? Well, let's spend some time and describe the Model View Presenter in more details.

Vocabulary for MVP and MVC

Sometimes you can hear: MVP is similar to MVC.
Then I have to say, yes, but as similar as is the C# similar to Java. You can read Java code very quickly. But if you’ll be sit to the PC with ‘Eclipse’ instead of Visual Studio, how long will take you to produce ‘Hello World’ application?
First of all we need to correctly ‘localize’ the words in both abbreviations. Look at this two triplets:
Model View Controller
Model View Presenter
For this article we will prefer MVC syntax and adjust MVP.

The first homophone word is Model.

MVC: Model == Plain container for storing references. Model has properties (ValueType, Objects even Collections) but does NOT have methods. This is great advantage of the Model, because whatever information you will need on View, put it in the Model - May be not so obvious but that's so wonderful place for AOP extending...
MVP: Model == Business. Model is not model as in MVC. It in fact represents the Business Facades or Services (or whatever you named it) which allows you to access objects (Entities, DataTables). This Model-Business mainly contains methods! Add(), Remove(), Update() ….

The second homophone word is View.  

MVC: View == View represents UI (user interface). View takes care for nice layout, smart controls, images, hyper-links. All that stuff is built from information stored in the Model. View exposes Controller's Actions via 'buttons' and 'links'. When they are clicked – ASP.NET MVC directly creates Controller and calls its Action – and the View itself is lost in the past.
MVP: View == Exposes properties to its Presenter, and as Presenter executes all needed calls to the Model-Business, assembles itself (View) by filling its exposed properties. The user’s requests are handled by Views methods. In these methods the Presenter is asked to communicate with Business and refill Exposed properties.

The third words are finally different not only by meaning but even by name

MVC: Controller == User requests are primarily routed to the Controller’s Actions. View at this moment only gathers the user inputs, which are transferred into Model. Controller then calls Business to ‘Get’, ‘Update’, ‘Delete’ etc. and refills the Model. Next the View renders the Model’s content.
MVC: Presenter == View creates and asks presenter to get or set data from Model-Business. After Presenter fills all exposed View’s properties, the execution continues on View side.

MVP Schema

Now if we know the real meaning of the abbr. words, we can look at the MVP example:
mvp3.png
The picture starts with user’s request. In the world of Web-Forms (WCSF) this event (I.) is handled by some of the life-cycle events on the view == page. Then the presenter is created and asked to get or set data (II.) from the Business (Model). Finally the Presenter fills the View’s exposed properties (III.) and the rendered view is as a response send to the user.
This approach was introduced also to improve test driven developmnet. The separation of concern (which is the crucial point of a good design) could be realized with the IView interface. This is what the Presenter knows and acts with. Presenter is responsible for exactly defined piece of work (discribed by the properties of IView) and can be easily reused. And also mock IView objects can be used to play the View role in unit tests.
Due to MVP the ASP.NET applications could be finally really well designed and multi-tier. There could be business tier (Model-Business), Pages with nice user interface without data dependency, and the workhorse (Presenters) which transfers data between those two.
And what’s more, that all is running with the Web-Forms as it is.

Implementation

Objects could (should) be created by some 'factories' using DI (Dependency injection == Inversion of Control IoC . The MVP design pattern will of course work without these techniques, but DI not only allows good testing but at first it force you to think about View and Presenter as the two independent objects.

public interface IView { IList<string> Links { get; set; } }
public interface IPresenter 
{ 
    IView View { get; set; }  // for pure DI (IoC) is set; enough
    void CreateLinks(); 
} 
 
public class View : IView
{
    // IView implementation
    public IList<string> Links { get; set; }
  
    // Presenter could be created by this View in constructor
    // or provided by IoC factory
    public IPresenter Presenter { protected get; set; } // public setter is enough;

    public View()   // instead of using IoC factory
    {               // let's create Presenter in View's constructor
        Presenter = new Presenter() { View = this };  // in this example ...
    }

    public void OnLoad()   // This method is called by ASP.NET
    {                      // as reaction on user's request
        Presenter.CreateLinks(); // View calls its Presenter    
    }
} 
 
public class Presenter : IPresenter
{
    // the center point for Presenter work is it's View
    public IView View { get; set; }

    // there could (should) be the Business call instead...
    public void CreateLinks()      // ...of the dummy example
    {
        View.Links = new List<string>() 
        {
            "http://www.codeproject.com/KB/applications/Catharsis.aspx"
          , "http://www.codeplex.com/Catharsis" 
        };
    }
}

So simple and wonderful the MVP design pattern is.

MVC for ASP.NET

After five years (or more) of promoting Web-Forms, Microsoft decided to establish (almost independent) team of Guru’s with only one aim: Break its treasury – Web-Forms. They (ASP.NET MVC team) in fact created very trivial (really very simple) http handlers which introduced MVC design pattern into ASP.NET.
How it works? Well, the ASP.NET page handler is removed. Instead there is the smart url routing hanlder, which transforms the user requests to Controller Action calls. That’s all.
Really, that’s all. There are some brilliants in the ASP.NET MVC implementation of course: among others the built-in AOP framework; very useful FORM-to-Model binding; etc. By the way, if you (or I) were smart enough (as these mentioned Gurus), we could do it ourselves years ago – just by using the ability of ASP.NET to change or extend the http handlers.

MVC Schema

Well how the MVC Design pattern works:
mvc3.png
The user’s request is send to the server, where is handled by URL-Routing handler. If user asks for http://MyServer/Person.mvc/List/ the handler translates it as: create Controller named Person and invoke its action “List”. So the starting point is the Controller at this design pattern.
(AOP – the ASP.NET MVC allows simply to append AOP filters before Action invocation and after Action execution. It enforces the separation of concern. Tremendous)
Controller’s Action then Sets or Gets data into persistence (I.) using Business (facades, services). The results (Collection, Items, CodeLists, NavigationLinks) are stored in the Model (II.). When Model is filled the View is asked to render the user output using the information stored in the Model (III.). View (page or control) communicates only with the Model.
One of the (at first sought not so clear) advantages of that approach is the AJAX support. If your application at some point need the combo-box (drop-down list) to be added into page, you can asynchronously call the Controller to fill Model with Items (options) and pass them to the UserControl which renders <select><option> …</select>. That small piece of xml could be easily sent to client browser and appended into the display tree.
public interface IModel { IList<strings> Links { get; set; } }
public class Model : IModel
{
    public IList<strings> Links { get; set; }
} 
 
public class LinkController    // Link Prefix is used to demonstrate URL routing
{
    protected IModel Model { get; set; } // e.g. this could be injected by IoC 
    protected IView  View  { get; set; } // or in constructor ... 

    // link on page should look 
    // http://MyServer/Link/ShowLinks  -- this is the source for URL routing 
    public virtual void ShowLinks() // the ENTER POINT
    {                               // ASP.NET MVC directly calls this method(Action)
        Model = new Model();        // instead of calling View.aspx !!!
        Model.Links = new List<string>() 
        {
            "http://www.codeproject.com/KB/applications/Catharsis.aspx"
          , "http://www.codeplex.com/Catharsis" 
        }; 
        
        View = new View();
        View.Show(Model);  
    }
}
 
public interface IView { void Show(IModel); }
public class View : IView
{
    // Model is container for data, directly supplied by Controller
    public IModel Model { get; set; }

    Show(IModel model) // this could be the .aspx page, but in contrast with MVP  
    {                  // View is created and firstly called by controller - not ASP.NET
        Model = model;
        // TODO fill html with elements according to the Model data ...
    }
}
What it brings? The cleanness and performance. No page.aspx was called! No events (Init, Load) were raised. No user Http handler was needed. Only your one simple Action was directly called (via URL routing) and the xml provided by UserControl was retrieved

No comments:

Change default Port on Next.js app

 If any other app or process is running on port 3000 , you will get this error in your terminal Port 3000 is already in use. error Command f...