Thursday, July 21, 2005

Declaration of event accessors.

In C# event accessors are used to add and remove event handlers in client code. By declaring custom accessors you can change subscription behavior.

Problem: Prevent a client object from subscribing to the same event multiple times.

Example: You have a view that contains a Navigate event which is raised when the user needs to navigate to the next page.
class View : IView
{
public event NavigationHandler Navigate;

...

public void raiseNavigate()
{
Navigate(typeof(View2));
}
}

When Navigate is raised a presenter should clear the existing view and present a new one.
class FormPresenter
{
... constructor inject a view factory ...

public void NavigateTo(Type type)
{
IView view = viewFactory.Find(type);
view.Navigate+=new NavigationHandler(NavigateTo);
changeView(view);
}
}

This code works well if a new view is returned by the viewFactory every time. However, if the same view is returned from the factory, the presenter will subscribe to the Navigate event multiple times.

Solution: Subscribe to the Navigate event only if the presenter hasn't previously. Declaring the event accessors allows us to manage a single Navigate subscription per client model in the publisher.

Thus, View becomes:
class View : IView
{
private NavigationHandler navigationHandler;

private ArrayList navigateSubscriberInstances = new ArrayList();

public event NavigationHandler Navigate
{
add
{
if (navigationHandler==null || !navigateSubscriberInstances.Contains(navigationHandler.Target))
{
navigationHandler += value;
navigateSubscriberInstances.Add(navigationHandler.Target);
}
}
remove
{
navigationHandler -= value;
navigateSubscriberInstances.Remove(navigationHandler.Target);
}
}

protected void raiseNavigate(Type type)
{
if (navigationHandler!=null)
{
navigationHandler(type);
}
}
}

2 comments:

  1. Anonymous8:43 AM

    Why would you ever want to make a field public on the View? Instead of exposing publicly an event, why not just require a method that accepts a delegate, and the view can add the delegate to the appropriate event.

    ReplyDelete
  2. Anonymous9:11 AM

    The model view presenter (MVP) implementation wasn't really the focus of the entry; however, I am interested in your suggestion. What do you gain by having a method add the delegate/

    ReplyDelete

Note: Only a member of this blog may post a comment.