Re-using a View in multiple use-cases

Oct 2, 2008 at 9:38 AM
Hi all,

I'm new to Prism so please excuse any daft questions! I did lots of work on a CAB implementation last year, and have been looking at the Stock Trader Reference Implementation.

My questions are:

1. I noticed in the RI that PresenterModels are accessing the Controllers (PositionSummaryPresentationModel). This was frowned upon in CAB - tight coupling a View/Presenter pair to the Controller removed all re-use from that View in different use-cases. What is the guidance here?

2.
Lets say I have a really re-usable view like selecting from a list of Customers. And I need to use it in a lot of use-cases - say finding orders, viewing accounts.
In old-skool CAB I used to raise an event scoped locally to my WorkItem - CustomerSelected. How would this scenario work in Prism?

A few options I can think of:

1. Use the EventAggregator and have the orders view subscribe to the CustomerSelected event raised by the CustomerList view... Not sure how this would work without being able to scope events to a particular use-case though.

2. Have a controller with a 'CustomerSelected' method. The Customer List can then call this method. The controller would have to implement an interface to allow the CustomerList to be used across different controllers though. Seems like effort, and links into my first point above. Should views / presentermodels be allowed to access the controllers directly?

3. Create a simple CustomerList user-control and just embed it directly into the Xaml for the OrderFinder, or the AccountViewer. Have both controls subscribe to a CustomerSelected event which that control raises.

3 seems like a really simple option to me. It's still testable as you could call the CustomerSelected event directly on each use-case which consumes the CustomerList.

Has anyone else has come across these issues? If so how have you tackled them? Am I just thinking too deep here!!

Thanks,

Graeme

Oct 2, 2008 at 8:16 PM
Hi Graeme, you may find the following thread interesting http://www.codeplex.com/CompositeWPF/Thread/View.aspx?ThreadId=36581; in this thread there are code examples, links to flash demo and blog on the topic.  

I prefer MVP over the PresentationModel for the reasons you noted - the Guidance (documentation) suggest both as options.
Oct 3, 2008 at 3:50 AM
Thanks Bill,

I had a read of the thread but am still not sure about it. I think this comes down to my dislike of a loosely coupled event approach where:

I 'select' a customer from the list
That causes a Customer Selected event to get raised
Someone else hears that event and shows a details view (or in the CAB case started a new work-item for that customer).

I don't like that because when I select that customer in the list, _I know_ that I have to display that details view. It's not an event. It's very much a command. I found CAB misused to loosely couple business processes or workflows which IMHO shouldn't be loosely coupled. Eventing is a way to broadcast that something has happened. A stock price has changed for example, or a Customer's details have changed. I don't believe they should be used to control program flow or workflows. It's too confusing.

We had the situation where events were being raised, but the modules that handled them weren't there... Double click a customer over here, raise a CustomerSelected event... The user expects the customer details, but nothing happened because the subscribing module for whatever reason wasn't there.

I like the idea of a CustomerUI Service - when the customer is selected in the list we call the service to say 'DisplayCustomerDetails'. It would then be up-to the service to decide how best to display it.

Graeme

Oct 3, 2008 at 11:55 AM
Edited Oct 3, 2008 at 11:58 AM
Perhaps I can convince you...   I'll be working on wrapping up my MEFContrib contribution this weekend, I'll create the actual application (completed proof of concept last night) with you in mind so that you can see the benefits.  Note: we're on 4/10s so my weekend doesn't end until Monday night ;)
Oct 3, 2008 at 1:31 PM
Cool - I look forward to seeing it. I'll be really intrigued to see how it's done.
I don't know what a 4/10 is but it doesn't sound like fun!!!

Graeme
Oct 3, 2008 at 3:51 PM
I guess that wouldn't be to clear outside the context of my workplace :O, it's what our team calls the new shifts that we started to cover different time zones :)  We work four ten hour days.

I'll be providing plenty of details and examples on how everything works.   I'll be covering regions, event aggregation, commands and how MEF allows us to easily create Add-ins.  I'll also throw workflow, LINQ and entity framework into the mix; I remember how I wished the Smart Client Software Factory had provided real-world data access examples.  

FYI, the MEFContrib contribution will be the foundation for my SDMS project (http://www.CodePlex.com/SDMS) so interested parties will be able to see it grow there.
Oct 8, 2008 at 4:41 AM
Hi Graeme,  I have a flash demo for the concepts I'm about to present => http://www.global-webnet.net/flash/demo/MEFSDMS.0.0.0.htm.

Although this is a MEFContrib project all of the applicable features are CompositeWPF.  The code is available at http://www.CodePlex.com/MEFContrib.   The applicable projects will be relative to the MEFApp | MEFSDMS folder within the solution.  Bear in mind that MEFContrib project development will be focused on core requirements and is in it's early stages.   Before it is released (which obviously won't be before MEF is released) the MVP pattern will be applied to all controls; in the interim you'll find code in code-behind.

The MainView project's MainModule.cs  loads the MainView.  The MainView has a number of regions which will be populated by other project's views; specifically the RSSFeed, RSSFeedView and UserView (as shown by the flash demo).  

Important to understanding the app - the MenuItem.Click and Button.Click routed events are handled by a RoutedEventFactory class.  The MainView.Infrastructure project holds the MainController and MainPresenter (for the above mentioned MainView).  In the MainController you'll find that in the OnFactoryExecute() method I currently handle (publish) the ButtonClickEvent and MenuItemClickEvent routed events.  

<UserControl x:Class="MainView.Views.MainViewLayout"

  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

  xmlns:cal="http://www.codeplex.com/CompositeWPF"

  MenuItem.Click="RoutedEventHandler"

  Button.Click="RoutedEventHandler">

 

<!--EndFragment-->
You will find that this application is loosely coupled and there are events flying all over the place.  The reason it will be managable is because Buttons, Menus and status messages will be published in applicable areas with no regard to subscribers.   

Subscribers *ONLY* worry about their applicable view, e.g., in the MainView project, MainViewLayout.xamls.cs code-behind you'll find the ButtonClickHandler and GenericHandler populating it's left and right statusbar.  Later, the statusbar will be another region and the referenced code will be in its presenter.

The benefit is that no matter how large the program gets, no matter how many Views are open, each process only manages itself so if a status bar isn't working correctly or a menu option does not respond there is only one place to look - the Module, Controller or Presenter that has responsibility for that UI component.