Model View Presenter on Asp.Net using WebFormsMVP framework

image

Slightly more than a year ago, I wrote two posts on opting for MVC pattern on Asp.net Webform (Asp.Net MVC without using ’˜the framework part1 and part 2: a good example of unit testing). A few months ago, I heard about Tatham Oddie's project WebForms MVP, which until yesterday I totally forgot about. All thanks to @mosessaur's tweet, I decided to have a quick look at it and really loving it!

The View: Webform as a template engine

Asp.Net Webform is designed to be a Smart UI platform. What that means, it more than just layout engine...alot more! Just look at controls such as ObjectDataSource, UpdatePanel or any other Asp.Net Ajax Control Toolkit controls, they are much richer than just UI elements but also dictate behaviors.

In the WebFormsMVP framework, Asp.Net Webform is meant to be used as just a templating engine. I'm not saying that you can't, but better not to unless if you have strong reasons (such as using ready made controls etc). The goal is to push as much smartness to the presenters.

The view then becomes really simple.

<form id="Form1" runat="server">
  <% // Model is a strong type property bag for the data binded to the view %>
  <%= Model.Owner %>
  <%= Model.Description %>
</form>

If you look at the Default.aspx code above, it looks similar to what classic Asp or Asp.Net MVC view would look like. What's worth noting is the property Model which is a property bag to access the model binded to this view (popularly known as View Model).

The type of the property Model is defined through Generics in the base class of the page. So in the code behind we will have the following:

 public partial class Default : MvpPage<WorkModel>
 {
     protected void Page_Load(object sender, EventArgs e)
     {
     }
 }

MvpPage and MvpUserControl base classes are a part of the WebFormsMVP framework and takes a type of T.  The WorkModel  in this case contains the .Owner and .Description properties.

Also note that the code behind is practically empty (in a slightly more complex : real life scenario, code behind will contains event propagation: button has just been clicked, etc)

The Presenter listens to the View

Model View Controller prescribes that the controller should be the first class citizen in responding to any requests.  However, in Model View Presenter, the View takes on this responsibility. The view propagates the events to the Presenter. Presenter will decide what need to happen next (read more: Difference between MVP and MVC).

Therefore you will have the following Presenter class. Notice how in the constructor we subscribe to the View's Load event and react upon it.

 // notice the base class which takes the T of the view
 public class DefaultPresenter : Presenter<IView<WorkModel>>
 {
     // required constructor by the base class
     public DefaultPresenter(IView<WorkModel> view) : base(view)
     {
         // subscribe to the view's events :
         // in this case the Load event
         View.Load += View_Load;
     }

     // required method by the base class
     public override void ReleaseView()
     {
         // clean up the delegate by detaching it
         View.Load -= View_Load;
     }

     // the core logic of the app where the Model is instantiated, fetched
     // and binded to the view
     private void View_Load(object sender, EventArgs e)
     {
         View.Model.Owner = "Ron";
         View.Model.Description = "to blog about WebFormMVP";
     }
 }

Presenter and View binding

image

There are 4 different ways of binding, 2 of which I have little knowledge about. So let me explain to you the two that I know:

  1. Convention - By default, the WebFormsMVP framework look for the Presenter class with the same type name as the View (with the word ’˜Presenter' as the suffix). It also tries to find it in different namespaces.

    for e.g view with type Default will be looking for a class called DefaultPresenter

  2. Attributes - I could also explicitly map the View to the Presenter by using an attribute like so:
[PresenterBinding(typeof(DefaultPresenter), ViewType = typeof(IView<WorkModel>))]

Conclusion

WebFormMVP framework allows nice clean separation just like Asp.Net MVC without necessarily throwing away all our investment on web controls. We get the productivity from the compositional nature of web controls when we need it, and still get the clean separation of the MVP pattern : without as much work as doing everything yourself.

Once we start looking into Cross Presenter Messaging, things will get even more interesting. I bet you that this very feature will get rid of the complexity of the usual page life cycle.

Let me support that argument: alot of times, asp.net page lifecycle becomes an issue when we're dealing with controls having to rely on data that is fetched by another control and not being ready at a particular stage in a page lifecycle. Cross Presenter Messaging will eliminate the problem by providing a publisher/subscriber mechanism to pass around data between all these web controls without having too much knowledge of the inner mechanics of how they individually work. More on that later.

I used Asp.Net 4.0 with WebFormsMVP CTP 7

  1. Ronald Widha » Blog Archive » a simple example of the WebFormsMVP Cross Presenter Messaging says:

    [...] my last post, I covered the basics of WebFormsMVP framework. On this post, I want to talk about a feature of the framework that I really really fall in love [...]

  2. Bharath Techmail says:

    Can you please share the SOURCE Code sample that you evaluated for webformsMVP?

  3. Richard Mc Cannon says:

    simple project sample is needed ! i am a practical person and lazy enough to read all sentence writter above...i need the working sample.. please

  4. Rahman Mahmoodi says:

    Good article mate! Did you finally out the other two ways to bind View with Presenter? ;-) Rahman