Click here to Skip to main content
15,880,469 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I’m using MVP pattern for a payroll system as my final year project. There are about 16 entity classes (like employee, client, salary etc.) in the analyzed problem and I have designed the solution as follows…

No of UIs(Views) – 18,
Separate Presenters and Models for each UI ( 18+18) ,
One Data Service (repository) catering to all presenters.
Each view, model and the data service implement interfaces and use dependency injection (constructor Inj).

Already I have implemented one UI and below is the code… This code compiles and runs giving the desired output.
My questions are…

1. What would be the consequences of applying this pattern, at the end of the project good? or bad? (As I don’t have a previous experience)
2. Any considerable flows in this pattern or in the code?
3. Is this pattern suitable for a project at this level?
4. Any advises to improve this?

Please note that my final ambition is to finish the project with the schedule and to pass the evaluation. So actually now what I want is to build confidence that I’m going the right direction.
Could you experts help me? Answers covering my all questions are mostly welcomed.
Thank you.

View

C#
namespace Payroll
{
    public delegate void ViewEventHandler(object sender, EventArgs e);

    public partial class frmNewClient : Form, IClientView
    {
	//Properties
        public int CID
        {
            get {return Convert.ToInt32(txtCID.Text); }
            set { txtCID.Text=value.ToString();}
        }

        public string ClientName
        {
            get { return txtCName.Text; }
            set { txtCName.Text = value; }
        }
.
.
.

        public frmNewClient()
        {
            InitializeComponent();
        }
        //Raise events, first to update model and then to save data to database
        private void cmdSave_Click(object sender, EventArgs e)
        {
            DataChanged(sender, e);
            Save(sender, e);
        }
	//Even handlers 
        public event EventHandler DataChanged;
        public event EventHandler Save;
        public event EventHandler Search;
        }
}


Model
C#
namespace Payroll
{
    class Client: IClient
    {
	//Properties
        public int CID { get; set; }
        public string ClientName { get; set; }
        public string ClientAdd { get; set; }
        public string ContactPerson { get; set; }
        public string ClientMob { get; set; }
        public string ClientTel { get; set; }
        public string Remarks { get; set; }
        public DateTime EnteredDate { get; set; }
        

        //Custom constructor with parameteres
        public Client(int CID, string clientName, string clientAdd, string contactPerson, string clientMob, string clientTel, string Remarks, DateTime enteredDate)
        {
            this.CID = CID;
            this.ClientName = clientName;
            this.ClientAdd = clientAdd;
            this.ContactPerson = contactPerson;
            this.ClientMob = clientMob;
            this.ClientTel = clientTel;
            this.Remarks = Remarks;
            this.EnteredDate = enteredDate;
        }

        //Default constructor
        public Client()
        {
        }
    }
}


Presenter
C#
namespace Payroll
{
    class ClientPresenter
    {
        IClient _model;
        IClientView _view;
        IDataService _ds;

		//Constructor 
		public ClientPresenter( IClient model,IClientView view, IDataService ds)
		{
            		this._ds = ds;
			this._model = model;
			this._view = view;
			this.SetViewPropertiesFromModel();
			this.WireUpViewEvents();
		}
		//This will wire up the custom method provided to event
		private void WireUpViewEvents()
		{
			this._view.DataChanged +=new EventHandler(_view_DataChanged);
            		this._view.Save += new EventHandler(_view_Save);
            		this._view.Search += new EventHandler(_view_Search);
		}

//Following code snippet will sinc the parameters of the view with the parameters of the model and vice versa. (All text boxes in the UI are encapsulated in properties)
//======================================================================================       
		private void SetModelPropertiesFromView()
		{
            foreach (PropertyInfo viewProperty in this._view.GetType().GetProperties())
            {
                if (viewProperty.CanRead)
                {
                    PropertyInfo modelProperty = this._model.GetType().GetProperty(viewProperty.Name);

                    if (modelProperty != null && modelProperty.PropertyType.Equals(viewProperty.PropertyType))
                    {
                        object valueToAssign = Convert.ChangeType(viewProperty.GetValue(this._view, null), modelProperty.PropertyType);

                        if (valueToAssign != null)
                        {
                            modelProperty.SetValue(this._model, valueToAssign, null);
                        }
                    }
                }
            }
		}
		
		private void SetViewPropertiesFromModel()
		{
			foreach (PropertyInfo viewProperty in this._view.GetType().GetProperties())
			{
				if (viewProperty.CanWrite)
				{
					PropertyInfo modelProperty = this._model.GetType().GetProperty(viewProperty.Name);

					if (modelProperty != null && modelProperty.PropertyType.Equals(viewProperty.PropertyType))
					{
						object modelValue = modelProperty.GetValue(this._model, null);

						if (modelValue != null)
						{
							object valueToAssign = Convert.ChangeType(modelValue, viewProperty.PropertyType);

							if (valueToAssign != null)
							{
								viewProperty.SetValue(this._view, valueToAssign, null);
							}
						}
					}
				}
			}
		}
//====================================================================================== 

        private void _view_DataChanged(object sender, EventArgs e)
        {
            this.SetModelPropertiesFromView(); // Updating the model properties when data in the view properties changed…
        }

        private void _view_Save(object sender, EventArgs e)
        {
            this.Save();
        }

        private bool Save()
        {
            return _ds.InsertClient(_model);
        }

        private void _view_Search(object sender, EventArgs e)
        {
            this.Search();
        }

        private void Search()
        {
            var obj = _ds.GetByCID(_model.CID);

            if (obj != null)
            {
                _model = obj;
                this.SetViewPropertiesFromModel(); //Updating the view properties from the model if an object returned from GetByCID() method
            }
        }
    }
}


DataService
C#
namespace Payroll
{
    class DataService :IDataService
    {
       public bool InsertClient(IClient newClient)
        {
            string InsertStatement = @"BEGIN INSERT INTO client(Client_Name, C_Add, Contact_Person, C_Mob_No, C_Tel_No, Remarks, Ent_Date)" +
                                    " VALUES (@CName, @CAdd, @CPerson, @CMob, @CTel, @Remarks, @entDate) END";

                using (SqlConnection newCon = new SqlConnection(db.GetConnectionString))
                {
                    using (SqlCommand SqlCom = new SqlCommand(InsertStatement,newCon))
                    {
                        try
                        {
                            SqlCom.Parameters.Add("@CName", SqlDbType.VarChar).Value = newClient.ClientName;
                            SqlCom.Parameters.Add("@CAdd", SqlDbType.VarChar).Value = newClient.ClientAdd;
                            SqlCom.Parameters.Add("@CPerson", SqlDbType.VarChar).Value = newClient.ContactPerson;
                            SqlCom.Parameters.Add("@CMob", SqlDbType.Char).Value = newClient.ClientMob;
                            SqlCom.Parameters.Add("@CTel", SqlDbType.Char).Value = newClient.ClientTel;
                            SqlCom.Parameters.Add("@Remarks", SqlDbType.VarChar).Value = newClient.Remarks;
                            SqlCom.Parameters.Add("@entDate", SqlDbType.Date).Value = newClient.EnteredDate;
                            SqlCom.Connection = newCon;
                            newCon.Open();

                            SqlCom.ExecuteNonQuery();
                            return true;
                        }
                        catch (Exception e) { MessageBox.Show(("Error: " + e.Message)); }
                        if (newCon.State == System.Data.ConnectionState.Open) newCon.Close();
                        return false;
                    }
                }
        }

        public Client GetByCID(int CID)
        {
            string SelectStatement=@"SELECT * FROM client WHERE CID=@ID";

                using (SqlConnection NewCon = new SqlConnection(db.GetConnectionString))
                {                    
                    using (SqlCommand SqlCom = new SqlCommand(SelectStatement,NewCon))
                    {
                        SqlCom.Parameters.Add("@ID", SqlDbType.Char).Value = CID;

                        try
                        {
                            NewCon.Open();
                            using (SqlDataReader NewRdr = SqlCom.ExecuteReader())
                            {

                                if (NewRdr.Read())
                                {
                                    return new Client
                                    {
                                        CID = NewRdr.GetInt32(0),
                                        ClientName = NewRdr.GetString(1),
                                        ClientAdd = NewRdr.GetString(2),
                                        ContactPerson = NewRdr.GetString(3),
                                        ClientMob = NewRdr.GetString(4),
                                        ClientTel = NewRdr.GetString(5),
                                        Remarks = NewRdr.GetString(6),
                                        EnteredDate = NewRdr.GetDateTime(7)
                                    };
                                }
                                return null;
                            }
                        }
                        catch (Exception e) { MessageBox.Show(("Error: " + e.Message)); }
                        if (NewCon.State == System.Data.ConnectionState.Open) NewCon.Close();
                        return null;                        
                    }                                 
                }
        }
        }
}


Programme
C#
private void btnClient_Click(object sender, EventArgs e)
{
    IClient Client = new Client();
    IClientView ClientView = new frmNewClient();
    IDataService ds = new DataService();

    new ClientPresenter(Client, ClientView, ds);
    ClientView.ShowDialog();
}
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900