dotNetChris @ Marisic.Net

February 16, 2009

Creating a generic Model-View-Presenter framework

With all of the current talk about ASP.NET MVC it seem dated to bring up the model view presenter architecture but I still believe it’s a very strong pattern in separating UI logic from application design. This post is meant to offer a successor to the Web Client Software Factory (WCSF) framework provided by Microsoft. In last usage of WCSF I encountered numerous errors stemming from ObjectBuilder during the dependency injection of WCSF which is what lead me down the road of creating UnityWeb which has evolved into StructuredWeb. The rest of this post will include no specific dependencies except 1 to StructureMap to handle the actual resolution of objects through dependency injection. This could be very easily replaced by Unity or any other inversion of control framework that supports the BuildUp() method. For a framework that does not support a BuildUp operation it will make things more complicated and that will need to be solved by your case basis.

Firstly, what is the model-view-presenter (MVP) pattern? The View is defined as an interface that the Presenter will use for getting and setting data to and from the Model. The View implementation will instantiate the Presenter object and provide a reference to itself (the formal constructor parameter is the View interface while the actual parameter is a concrete View class). When the event methods of the View are triggered, they will do nothing but invoke a method of the Presenter which has no parameters and no return value. The Presenter will then get data from the View, through the View interface variable that the Presenter stored when the constructor was called. The Presenter then invokes methods of the Model, and sets data from the Model into the View through the View interface.

From a layering point of view, the Presenter class might be considered as belonging to the application layer in a multilayered architectured object-oriented system with common layers but it can also be seen as a Presenter layer of its own between the Application layer and the User Interface layer.

[/source]

Now if you’re at all like me you will have almost no more of an idea what the MVP pattern is supposed to do after that explanation. To generalize on that statement it’s basically taking the interaction of the UI and the application logic which usually is coupled together and separating it into 3 areas.

The model – this is the application logic which will be housed in controller classes.

The view – which is an interface which abstracts the UI away, all data sent and retrieved from the UI is done through this interface

The presenter – this is a mediator that negotiates how the UI and application logic interact. The view is also a composition of this class.

Starting with the view:

public interface IView
{
}

This is the most basic of the basic of interfaces, for my needs it’s purely a marker interface. If every single one of your pages shares a common property perhaps an event message collection this would be a good place to define a property for it.

The presenter class:

public abstract class Presenter<TView> where TView : IView
{
    public TView View { get; set; }

    public virtual void OnViewInitialized()
    {
    }

    public virtual void OnViewLoaded()
    {
    }
}

The OnViewInitialized method is to represent any operations you would execute in Page_Load if(Page.IsPostback == false) so only on the initial page load. The OnViewLoaded method represents all page loads whether or not they are post backs. Currently I have no global page operations since I have no global view properties. This class is also constrained that each TView for a presenter is also an IView, this will be important later.

Next creating a view:

public interface IEmployeeView: IView
{
    IList<Employee> Employees { get; set; }
    IList<Employee> EmployeesListDatasource { set; }
}

As you can see my view will have 2 properties one for getting or setting a collection and another for setting only the same type. The view also implements the marker interface IView.

Creating the presenter:

public class EmployeePresenter : Presenter<IEmployeeView>
{
    private readonly IEmployeeController _controller;

    public EmployeePresenter(IEmployeeController controller)
    {
        _controller = controller;
    }

    public override void OnViewInitialized()
    {
        View.Employees = _controller.GetEmployees();
    }

    public override void OnViewLoaded()
    {
        View.EmployeesListDatasource = View.Employees;
    }
}

I’m not going to go into the details of the IEmployeeController this is the “model” where actual application code is ran there is nothing special about this class or it’s interface and only contains logic specific to getting my set of employees. As you can see the EmployeePresenter implements Presenter. I overrided both of the methods provided by the Presenter base where the Initialize method gets list from the model and the loaded method binds the list to a datasource.

Now before I move onto implementing the IEmployeeView inside a page I’m going to create an abstract base page that will handle the dependency injection build up for my MVP framework.

public abstract class ViewBasePage<TPresenter, TView> : Page
    where TPresenter : Presenter<TView>
    where TView : IView
{
    protected TPresenter _presenter;

    public TPresenter Presenter
    {
        set
        {
            _presenter = value;
            _presenter.View = GetView();
        }
    }

    /// <summary>
    /// Gets the view. This will get the page during the ASP.NET
    /// life cycle where the physical page inherits the view
    /// </summary>
    /// <returns></returns>
    private static TView GetView()
    {
        return (TView) HttpContext.Current.Handler;
    }

    protected override void OnPreInit(EventArgs e)
    {
        ObjectFactory.BuildUp(this);
        base.OnPreInit(e);
    }
}

This class might look quite a bit strange, the majority of it is from the class definition it’s setup to only allow you to inherit it in a valid way such as: ViewBasePage<EmployeePresenter,IEmployeeView>. On the Presenter set method this is where the page actually becomes part of the composition of the Presenter (the description from Wikipedia said this).

The GetView method also probably looks strange what this is doing is getting the physical page that’s being instantiated by ASP.NET. The reason I’m doing this is it makes it easier to reference the page generically otherwise I would be required to do something smilar to

return (TView) (object) this

Which is borderline wrong since THIS technically refers to the ViewBasePage which does not implement the interface that TView consists of but at runtime eventually resolves correctly since a Page will implement the interface that makes up TView and not cause a runtime error.

This class overrides Page’s OnPreInit method to call ObjectFactory.BuildUp() which will cause all the dependency resolution to take place. In my specific usage of StructureMap I have it identify all Presenter properties as targets for dependency injection, in your case you may be required to use the [Setter] attribute from SturctureMap or the [Dependency] attribute from Unity or some other similar convention in other inversion of control frameworks.

Now finally onto the actual page.

public partial class _Default :
    ViewBasePage<EmployeePresenter, IEmployeeView>, IEmployeeView
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            _presenter.OnViewInitialized();
        }

        _presenter.OnViewLoaded();
        Page.DataBind();
    }

    #region Implementation of IEmployeeView

    IList<Employee> IEmployeeView.Employees
    {
        get { return ViewState["IEmployeeView.Employees"] as IList<Employee>; }
        set { ViewState["IEmployeeView.Employees"] = value; }
    }

    IList<Employee> IEmployeeView.EmployeesListDatasource
    {
        set { lstEmployees.DataSource = value; }
    }

    #endregion
}

This class inherits the ViewBasePage class and implements the IEmployeeView. The _presenter field is in the ViewBasePage and contains the fully resolved dependency to EmployeePresenter. As I stated in the portion of the presenter code you can see where OnViewInitialized() and OnViewLoaded() are called inside the page life cycle.

Implementing the IEmployeeView you have the properties target actual controls on the page or the ViewState / QueryString etc that is available to the page. Now if you remember the code in my actual EmployeePresenter it should make sense why in ViewInitialized the Employees property is set by the controller and on the ViewLoaded the Employees property is assigned to the EmployeesListDatasource since it’s just refreshing the data source to the view state collection on subsequent page post backs.

kick it on DotNetKicks.com

Shout it

BloggingContext.ApplicationInstance.CompleteRequest();

About these ads

9 Comments »

  1. Creating a generic Model-View-Presenter framework « dotNetChris @ Marisic.net…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

    Trackback by DotNetShoutout — February 16, 2009 @ 4:14 am

  2. Creating a generic Model-View-Presenter framework « dotNetChris @ Marisic.net…

    DotNetBurner.com – news and articles about .net DotNetBurner…

    Trackback by Creating a generic Model-View-Presenter framework « dotNetChris @ Marisic.net - DotNetBurner — February 16, 2009 @ 4:14 am

  3. [...] bookmarks tagged concrete Creating a generic Model-View-Presenter framework saved by 3 others     Gameshowparodies bookmarked on 02/16/09 | [...]

    Pingback by Pages tagged "concrete" — February 16, 2009 @ 6:01 am

  4. Hi,
    I really like what you have done here.

    I need to do something that works for both windows and web.
    I dont see how I can apply this to windows .

    Any suggestions.

    Comment by gb — February 26, 2009 @ 7:53 pm

  5. @GB

    I had wondered if anyone was going to bring up using this on a winform application, what’s great is this is almost exactly the same. The only differences instead of having a base page inheriting from system.web.ui you will be inheriting a base form from system.forms? It’s been a while since I’ve done WinForms so you’ll have to verify some of my statements yourself.

    Basically you’ll do the same as my base page except it will be inherited from the forms and make this be what every one of your forms in your application inherits from.

    You will override the Initialization method in the base form (or the similar method, I’m not 100% of the names anymore) with the same code I have in my base page. The only difference in my GetView() method you will need to change it to not be static and the code to be:

    return (TView) HttpContext.Current.Handler;

    to be

    return (TView) (object) this

    While it’s a little weird looking it should be fine since the constraints that are applied to the base class will make sure that at runtime it will always be able to cast THIS to the TView and not generate a runtime exception.

    Let me know how this works for you, if you have any questions please let me know.

    Chris

    Comment by dotnetchris — February 26, 2009 @ 10:04 pm

  6. [...] Creating a generic Model-View-Presenter framework [...]

    Pingback by Model-View-Presenter(MVP) :: Pattern « NitRiX Reloaded – The Life & Dreams of Nithin Mohan T K — December 31, 2009 @ 9:41 am

  7. hi,
    very good article. i like the architecture.

    i tried to apply your architecture in a sample demo.

    the presenter is not initialized. i get null pointer exception n the _presenter property in the class _Default.

    where i have to initialize the _presenter property?

    any idea?

    thank you.

    Comment by naji — December 19, 2011 @ 6:12 am

    • Naji, sorry its a little bit behind for me to answer.

      For the actual creation of the Presenter object, you need to leverage an Inversion of Control library, The one I use is StructureMap, a rough configuration on how I handle View & Presenter scanning and registration using StructureMap would be:

      //Handle web app special case for MVP
      Scan(scanner =>
      {
      //web app proj
      scanner.TheCallingAssembly();

      scanner.Exclude(x => x.IsTypeOf<IView>());

      scanner.RegisterConcreteTypesAgainstTheFirstInterface()
      .OnAddedPluginTypes(x => x.LifecycleIs(InstanceScope.Hybrid));
      });

      //Load View injection
      Scan(scanner =>
      {
      //web app proj
      scanner.TheCallingAssembly();

      //Does the magic dynamic resolving of the view at runtime since StructureMap
      //can never be the instaniator of any of the IView conrete implementations since
      //they are physical ASP.NET web pages and the page creation is locked internal
      scanner.With(new ViewScanner());
      });

      These scan methods go in a constructor of a StructureMap Registry class, the view scanner I use above would be:

      public class ViewScanner : IRegistrationConvention
      {
      public void Process(Type type, Registry registry)
      {
      if (type.IsTypeOf() && !type.IsConcreteType())
      {
      registry.For(type).LifecycleIs(InstanceScope.Hybrid).Use(c => HttpContext.Current.CurrentHandler);
      }
      }
      }

      Comment by dotnetchris — January 27, 2012 @ 6:55 pm

  8. va chier

    Comment by sam — January 13, 2012 @ 4:22 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Shocking Blue Green Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 242 other followers

%d bloggers like this: