Bubble presenter events to parent module

Topics: Prism v2 - Silverlight 3
Aug 31, 2009 at 4:54 PM

I have a desire to handle an event in my presenter (which is the context of a given view) and have that handler initiate a function in the module that created the presenter. What is the preferred approach? For my scenario, I'd rather not have the function be a global command - it really isn't global. I just want the module to be able to handle this functionality for all the presenters it creates....

 

Thanks for any suggestions.

Aug 31, 2009 at 4:56 PM

Is it simply to pass a reference to the module when constructing the presenter?

Aug 31, 2009 at 5:40 PM

Hi

The way I would achieve this functionality is the following:

  1. When the module is created instantiate a ModuleController or a similar control that is in charge of coordinating the entire module functionality.
  2. This ModuleController is in charge of instantiating the presenters, so you can keep a reference to it in the Presenter.
  3. When the presenter handles the event it should call the ModuleController's method you want called (or you can raise a .NET event in the Presenter and subscribe to it in the Controller).

You can read more about similar topics in these blog posts:

Please let me know if this helps.

Damian Schenkelman
http://blogs.southworks.net/dschenkelman

Aug 31, 2009 at 6:09 PM

Cool. So what is the architectural reasoning for adding a ModuleController and not putting the logic in the module?

 

Thanks for your reply.

Aug 31, 2009 at 6:28 PM

I recall demos in the Smart Client Software Factory doing something similiar to what you suggested - particularly for events.    I grabbed a demo application that I used for a blog (full source HERE) and applied your idea to the existing Module class.  

The changes required to implement are in bold italics below - I use a Presentation Model (aka View Model) but I think you'll get the point as I show how I can use the Unity Container to pass in the module reference:

 MODULE CODE FOLLOWS:

public class ModuleAModule : IMyModule
{
    private readonly IRegionManager regionManager;
    private IUnityContainer container;
    private IEventAggregator aggregator;

    public ModuleAModule(
        IRegionManager RegionManager, 
        IUnityContainer container,
        IEventAggregator aggregator)
    {
        this.regionManager = RegionManager;
        this.container = container;
        this.aggregator = aggregator;
    }


    public void Initialize()
    {
        container
            .RegisterInstance<IMyModule>(this)
            .RegisterType<IMyControl, MyControl>(new ContainerControlledLifetimeManager())
            .RegisterType<IEntityDataService, EntityDataStub>()
            .RegisterType<IMyControlPresentationModel, MyControlPresentationModel>(
                new ContainerControlledLifetimeManager()); // Singleton

        // The presenter gets resolved first which in turn resolves the
        // view as configured above
        regionManager.RegisterViewWithRegion("MainRegion",
            () => container.Resolve<MyControlPresenter>().View);

    }

    public void MyGlobalProcess(IPresenter presenter)
    {
        MyControlPresentationModel model = presenter.DataContext as MyControlPresentationModel;
        Debug.WriteLine(string.Format("Total number of Entities = {0}", 
            model.TestEntities.Count),"GLOBAL PROCESS");
        
    }

}
PRESENTER CODE FOLLOWS:
public class MyControlPresenter : PresenterBase<IMyControl>, IPresenter
{
    private IEntityDataService entityService;
    private IMyControlPresentationModel model;
    private IMyModule module;

    public object DataContext
    {
        get { return View.DataContext; }
        set { View.DataContext = value; }
    }

    public MyControlPresenter(
        IMyControl view, IUnityContainer container, IMyControlPresentationModel model,
        IMyModule module, IEntityDataService entityService) : base(view, container, model)
    {
        this.entityService = entityService;
        this.model = model;
        this.module = module;
    }

    protected override void OnProcessEvent(ProcessEventArgs e)
    {
        entityService.GetEntityList(model.TestEntities);
        module.MyGlobalProcess(this);
    }
}
 
Sep 1, 2009 at 4:49 PM

Thanks for the input.