Search code examples
c#asp.netwebformstddmvp

Webforms MVP Passive View - event handling


Should the view have nothing event specific in its interface and call the presenter plain methods to handle events and not have any official EventHandlers? For instance

// ASPX
protected void OnSaveButtonClicked(object sender, EventArgs e)
{
  _Presenter.OnSave();
}

Or should the view have event EventHandlers defined in its interface and link those up explicitly to control events on the page

// View
    public interface IView
    {
 ...
        event EventHandler Saved;
 ...
    }

// ASPX Page implementing the view
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        SaveButton.Click += delegate { Saved(this, e); };
    }

// Presenter
    internal Presenter(IView view,IRepository repository)
    {
       _view = view;
       _repository = repository;
       view.Saved += Save;
    }

The second seems like a whole lot of plumbing code to add all over.

My intention is to understand the benefits of each style and not just a blanket answer of which to use. My main goals is clarity and high value testability. Testability overall is important, but I wouldn't sacrifice design simplicity and clarity to be able to add another type of test that doesn't lead to too much gain over the test cases already possible with a simpler design. If a design choice does off more testability please include an example (pseudo code is fine) of the type of test it can now offer so I can make my decision if I value that type of extra test enough. Thanks!

Update: Does my question need any further clarification?


Solution

  • In your view's interface you should have a reference to the save button and then everything is done in the presentor. This keeps your view free of code and your preseneter easily testable.

    // View interface
    public interface IView
    {
        Button SaveButton;
    }
    
    // View code behind
    public Button SaveButton
    {
       get { return btnSave; }
    }
    
    //  Presenter
    internal Presenter(IView view,IRepository repository)
    {
       _view = view;
       _repository = repository;
       view.SaveButton.Click += new EventHandler(Saved);;
    }
    
    void Saved(object sender, EventArgs e)
    {
       // do save
    }
    

    '