Thursday 7 June 2012

Post/Email–1: MVVM Light messaging, order of register and send is important

Recently a friend of mine asked me the following question on Facebook. I started writing a few sentences, which turned into a few paragraphs and before I knew it I was writing a very long reply. Then, something Scott Hanselman said on twitter came to mind:
"Every email you send is a blog post you didn't write. Stop writing emails.”
Because of this, I intend to write these “Post/Email” (or “Post over Email”) blog posts whenever someone asks me a question, so that other people would benefit from them :)
Here we go, with this question from my friend Saad Galib on facebook: it at all possible to pass data between ViewModels using MVVM light messaging without ViewModelLocator? Because in a blog i read that that some class needs to register for a message before it is sent to receive it. Right now i have no locator. i send a message from ViewModel-1 bound to page 1 and then navigate to page 2 which in turn creates viewmodel 2 and in that viewmodel's constructor i register for that kind of messages(broadcasted from viewmodel1)....but its not working....:(
and this i definitely not satisfying the condition i read as i mentioned above. is there any work around?
The short answer is: no. The "no" here isn't because of the ViewModelLocator itself, but rather because of what you mentioned later about the order in which the subscription and broadcast are done.
The Messenger implementation in MVVM Light is simple and straightforward. When you register an object to some event, it adds it to a dictionary; and when that particular event is sent, it goes through the corresponding objects in the dictionary and notifies them (by calling the corresponding registered action). Therefore, when an object subscribes to a certain event, it only gets notified of those instances of the event which occur after it has subscribed. Which is the logical thing to do.
I'm not aware of anything in MVVM Light that would help with your particular situation, but there are other, maybe not so elegant, methods to transmit data between objects in a loosely coupled way. One of them, which I used myself but I'm not sure whether it's a good practice or not, is to have some sort of "buffer" where an object can put some data for other objects to take out at some point in time (in my particular scenario, I used a class "Pipe" with a static member "Data" that I set in one VM and consume in the other).
Hope this helps

1 comment:

  1. I think your approach is brilliant. In the message, you can help only one person, and in the blog many readers will be able to find the answer to the question they are interested in. Because of my mba resume editing job I faced with many people everyday and explaining the same thing to everyone is tedious. So I'm with you.