MVP Pattern in action

MVP Pattern in action

This edition of blog post deals with a simple example of  MVP pattern in action.  Model View Presenter is a UI pattern which separates the
presentation concerns with the presentation logic.  There are three elements to it

  1. Model - This is the data or business object
  2. View   - The User interface dealing with displaying data.  It routes user commands to the presenter.
  3. Presenter - Interaction of UI with UI logic.  It retrieves the data from repositories, persistsit, manipulates
    it and determines how it will be displayed in the view.

The core strength of MVP is testability and view switchability.  You can create views for different environment like windows, mobile, web etc and share the same presentation logic.

Simple User case 1.

  1. Create a user with UserName, Password, Email and IsActive

We have taken a very simple user to understand the MVP pattern.  First lets draw the required class diagram so that we
can get the holistic view of the static structure

.

The above diagram is the CRUX of the MVP design.  This can be made more generic, but don't wannt' to make simple things comple for
demonstration purpose.

Code :  EditUserView.aspx

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Web.ViewContracts;
using Web.Presenter;

public partial class ManagerUser : BasePage, IUserView
{
    UserPresenter presenter;

    protected override void OnInit(EventArgs e)
    {
        presenter = new UserPresenter(this);
        base.OnInit(e);
    }
    #region IUserView Members

    public string Message
    {
        get
        {
            return message.InnerHtml;
        }
        set
        {
            message.InnerHtml = value;
        }
    }

    public string UserName
    {
        get
        {
            return txtUserName.Text;
        }
        set
        {
            txtUserName.Text = value;
        }
    }

    public string Password
    {
        get
        {
            return txtPassword.Text;
        }
        set
        {
            txtPassword.Text = value;
        }
    }

    public string Email
    {
        get
        {
            return txtEmail.Text;
        }
        set
        {
            txtEmail.Text = value;
        }
    }

 

    public bool IsActive
    {
        get
        {
            return chkActive.Checked;
        }
        set
        {
            chkActive.Checked = value;
        }
    }

    #endregion
    protected void btnSave_Click(object sender, EventArgs e)
    {
        presenter.Save();
    }
}
 

Code : UserPresenter.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Web.ViewContracts;
using Demo.Service;
using Demo.Service.Messages;
using Demo.Objects.Entity;
using System.Text;

///


/// Summary description for UserPresenter
///

///

namespace Web.Presenter
{
    public class UserPresenter
    {
        IUserView view;
        IUserService userService;

        public UserPresenter(IView userView)
        {
            view = userView as IUserView;
            userService = new UserService();
        }

        public void Save()
        {
            User user = new User();
            user.Email = view.Email;
            user.IsActive = view.IsActive;
            user.Password = view.Password;
            user.UserName = view.UserName;

            UserResponse userResponse = userService.Save(user);

            if (userResponse.Status == ServiceStatus.Success)
            {
                view.Message = userResponse.Message;
            }
            else
            {
                StringBuilder sb = new StringBuilder(100);
                sb.Append("

    ");
                    foreach (ErrorInfo error in userResponse.Errors)
                    {
                        sb.Append("
  • " + error.key + ":        " + error.message +  "
  • ");
                    }
                    sb.Append("
");

                view.Message = sb.ToString();
            }
        }
    }
}

Code : IView

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Web.ViewContracts
{
    ///


    /// Summary description for IUserView
    ///

    public interface IView
    {
        string ViewName { get; set; }
        string Message { get; set; }
    }
}

Code : IUserView

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Web.ViewContracts
{
    ///


    /// Summary description for IUserView
    ///

    public interface IUserView : IView
    {
        string UserName { get; set; }
        string Password { get; set; }
        string Email { get; set; }
        bool IsActive { get; set; }
    }
}

Code : User.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Demo.Objects.Entity
{
    public class User : BaseEntity
    {
        public string UserName { get; set; }
        public string  Password { get; set; }
        public string Email { get; set; }
        public bool IsActive { get; set; }

        public User()
        {     }
    }
}

Code : BaseEntity.cs

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Demo.Objects.Entity
{
    public class BaseEntity
    {
        public Guid Id { get; set; }
    }
}
 

Service Layer

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Demo.Service.Messages
{
    public class ResponseBase
    {
        public IList Errors { get; set; }
        public string Message { get; set; }
        public ServiceStatus Status { get; set; }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Demo.Service.Messages
{
    public class UserResponse : ResponseBase
    {
    }
}
 

IUserService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Demo.Objects.Entity;
using Demo.Service.Messages;

namespace Demo.Service
{
    public interface IUserService
    {
        UserResponse Save(User user);
        IList GetAll();
        User GetById(Guid id);
    }
}

UserService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Demo.Objects.Entity;
using Demo.Service.Messages;

namespace Demo.Service
{
    public class UserService : IUserService
    {

        public IList Validate(User user)
        {
            IList errors = new List();
            if (string.IsNullOrEmpty(user.UserName))
            {
                errors.Add(new ErrorInfo { key = "user", message = "User name cannot be empty" });
            }

            if (string.IsNullOrEmpty(user.Password))
            {
                errors.Add(new ErrorInfo { key = "pwd", message = "Password name cannot be empty" });
            }

            if (string.IsNullOrEmpty(user.Email))
            {
                errors.Add(new ErrorInfo { key = "email", message = "Email name cannot be empty" });
            }
            return errors;
        }

        public UserResponse Save(User user)
        {
            UserResponse userResponse = new UserResponse();

            IList errors = Validate(user);

            if (errors.Count > 0)
            {
                userResponse.Errors = errors;
                userResponse.Message = "Error validating user";

                userResponse.Status = ServiceStatus.ValidationError;
            }
            else
            {
                userResponse.Message = "Successfully submitted the user.";
                userResponse.Status = ServiceStatus.Success;
            }
            return userResponse;
        }

        public IList GetAll()
        {
            throw new NotImplementedException();
        }
       
        public User GetById(Guid id)
        {
            throw new NotImplementedException();
        }
    }
}

ErrorInfo.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Demo.Service
{
    public class ErrorInfo
    {
        public string key { get; set; }
        public string message { get; set; }
        public object Item { get; set; }
    }

    public enum ServiceStatus
    {
        Success,
        ValidationError,
        Failure
    }
}
 

The code is pretty straightforward to understand,  Do let a comment in case you require more clarification.   Read part II
here geekswithblogs.net/rajeshpillai/archive/2009/11/30/mvp2.aspx

Happy Coding !!!