1
\$\begingroup\$

In a Windows forms payroll application employing MVP pattern (for a small scale client) I'm planing user permission handling as follows (permission based) as basically its implementation should be less complicated and straightforward.

NOTE: System could be simultaneously used by few users (maximum 3) and the database is at the server side.

This is my UserModel. Each user has a list of permissions given for them.

class User
{
    string UserID { get; set; }
    string Name { get; set; }
    string NIC {get;set;}
    string Designation { get; set; }
    string PassWord { get; set; }
    List <string> PermissionList = new List<string>();
    bool status { get; set; }
    DateTime EnteredDate { get; set; }
}

When user login to the system it will keep the current user in memory.

For example in BankAccountDetailEntering view, I can control the permission to access a command button as follows.

 public partial class BankAccountDetailEntering : Form
    {
        bool AccountEditable {get; set;}

        public BankAccountDetailEntering ()
        {
            InitializeComponent();
        }

        private void BankAccountDetailEntering_Load(object sender, EventArgs e)
        {
            cmdEditAccount.enabled = false;

            OnLoadForm (sender, e); // Event fires...

            If (AccountEditable )
            {
                cmdEditAccount.enabled=true;
            }
         }
    }

In this purpose all relevant presenters (like BankAccountDetailPresenter) should aware of UserModel as well in addition to the corresponding business Model it is presenting to the View.

class BankAccountDetailPresenter
{    
    BankAccountDetailEntering _View;
    BankAccount _Model;
    User _UserModel;
    DataService _DataService;

    BankAccountDetailPresenter( BankAccountDetailEntering view, BankAccount model, User userModel, DataService dataService )
    {
        _View=view;
        _Model = model;
        _UserModel = userModel;
        _DataService = dataService;
        WireUpEvents();
    }

    private void WireUpEvents()
    {
        _View.OnLoadForm += new EventHandler(_View_OnLoadForm);
    }

    private void _View_OnLoadForm(Object sender, EventArgs e)
    {

        foreach(string s in _UserModel.PermissionList) 
        { 
            If( s =="CanEditAccount")
            {
                _View.AccountEditable =true;
                return;
            }
        }
    }

    public Show()
    {
        _View.ShowDialog();
    }
}

So I'm handling the user permissions in the presenter iterating through the list. Should this be performed in the Presenter or View? Any other more promising ways to do this? I'd appreciate it if you could review the code and provide your feedback.

\$\endgroup\$
2
\$\begingroup\$

Full disclosure: I haven't done much with windows forms applications, so I may be breaking some otherwise well known winforms programming patterns.

Permissions are better handled by a service, so that you can more easily unit test that layer, plus the permissions logic becomes portable between presenters to promote DRYness of your code (Don't Repeat Yourself).

public class UserPermissionsService
{
    private User _user = null;

    public UserPermissionsService(User user)
    {
        _user = user;
    }

    public bool CanEditAccount { get { return _user.PermissionList.Contains("CanEditAccount"); } }
}

Then to use it:

public partial class BankAccountDetailEntering : Form
{
    UserPermissionsService PermissionsService { get; set; }

    public BankAccountDetailEntering()
    {
        InitializeComponent();
    }

    private void BankAccountDetailEntering_Load(object sender, EventArgs e)
    {
        cmdEditAccount.enabled = PermissionsService.CanEditAccount;
    }
}

The BankAccountDetailEntering form would need to instantiate the user permissions service with the proper user object before the BankAccountDetailEntering_Load method gets called.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the answer. I cant understand the use of property UserPermissionsService PermissionsService { get; set; } in the form!. When instantiating user, the problem is how to keep the loged user object in memory and make it available for this BankAccountDetailEntering form? \$\endgroup\$ – CAD Jun 10 '14 at 11:35
  • \$\begingroup\$ I also had the same question, about how to get the user object. Where do you instantiate the BankAccountDetailPresenter object, because the user is passed into the constructor. \$\endgroup\$ – Greg Burghardt Jun 10 '14 at 12:51
  • \$\begingroup\$ Method injection solved the matter;) Program.cs instantiates the service and then, when the user details became available, the presenter inject the user to service object. Then the presenter assigns service instance to the said property in the form. So that load event can manage things as you said. Thank you very much! \$\endgroup\$ – CAD Jun 10 '14 at 13:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.