SaveAll Composite Command & RI.StockTrader example

Topics: Prism v4 - Silverlight 4
Jan 23, 2011 at 8:27 PM
public static class ContactsCommands
        public static CompositeCommand SaveAllContactsCommand = new CompositeCommand();

    public class ContactsCommandProxy
        public virtual CompositeCommand SaveAllContactsCommand
            get { return ContactsCommands.SaveAllContactsCommand; }

I would like to implement the SaveAll CompositeCommand, so that my childSaveCommands on each tab would subscribe to it. 

1) Just to make sure I understand it right, the reason we are wrapping the static class into a proxy, is to make sure there is no memory leak if the commands are not unregistered from the composite command? Since the proxy could be garbage collected once the ViewModel doesnt live anymore. 
But if the viewmodel registers to the static class directly and wouldnt unregister, GC can't collect the viewmodel in first place. Or if I am wrong what is the reason to use the proxy class?

2) The RI.Stocktrader is very confusing. I don't understand how the OrdersController class fits in there. It seems only TestableOrdersController (unit test) is using that class. Yet the controller class has the responsibility to register and unregister the child save commands to the composite command inside proxy. So it must be used somehow in the real app.
I just don't see how the controller class should be used. If I have a OrderModule, with one View and one ViewModel and I have set the view to export itself into a TabContol region on the shell, so that each instance would be landing on a new tabItem, how does the controller class fit in there?

Many Thanks,

Jan 23, 2011 at 10:44 PM
Edited Jan 23, 2011 at 11:54 PM

1. On page 130 of the guidance it says "Note:  To increase the testability of your code, you can use a proxy class to access the
globally available commands and mock that proxy class in your tests." when I look at the StockTraderRI that looks like exactly
what they are using it for. 

From the looks of it, you need to deregister global commands when you release the ViewModel.

Edit: If you look at StartOrder in the OrdersController you can see them doing the UnregisterCommand in the
CloseViewRequested delegate.

2. Take a look at PositionSummaryViewModel.  I find it helps to search for the Export of the class rather than the class name. 
OrdersController is exported as IOrdersController.

Edit: One thing note is that OrdersController is exported as Shared, so it will be Singleton.

And yes, it can be confusing, I'm still muddling my way through it.

I'm still fighting with the where does the controller fit issue myself, so I'll let some one else answer that one.

Jan 27, 2011 at 1:50 PM

Hi John,


Thanks for your help and advice. I have solved the issue in this way:


The Shell's MainRegion shall be a TabContainer. Each TabItem gets a closeButton templated, the button is bound to a command on the view Model.
The ViewModel in this case would be the ViewModel of the View hosted in the region. Within the handler of the command delegate I would do the unregistering for the CompositeCommand, however how do I remove the View in first place?

Therefore I had to refactor it. The CloseButton doesn't bind to the command anymore but uses a code-behind-shell eventhandler. WIthin the eventhandler I would do the removal of the active tab as planned. Now the challenge is how to unregister the command in a clean way?
In the underlying View that is hosted in that region, I go into the code-behind and subscribe to the Unloaded() event.  And do call my ViewModel's Command to unregister for the composite command like this:

Public ContactView(ContactViewModel vm)
this.Unloaded += (s, e) => vm.CloseContactCommand.Execute(null);

The moment the view is closed as previously described, the Unloaded event is fired and the command would unregister itself from the Composite Command.

What do you think of this idea?

Regarding Controller, I made some more research, it seems the Controller is only used for Presenter-First pattern.  You may find a good example of that on Prism Training Kit 4.0 project, excersice 4.
A fake ViewModel (without implementing NotificationObject nor any kind of INotifyPropertyChanged) is generated and the View is injected in it. The Controller class then holds the fake ViewModel.
Personally I don't see any use for a controller class yet, when you can use real MVVM classes.  It seems to be a remaining of old Prism 1.0/2.0 code.

Still investigating...