Search code examples
mvvmdependency-injectioninversion-of-controlviewmodeleventaggregator

ViewModel to ViewModel Communication


Given the following scenario:

  1. ViewModelA launches ViewModelB (via a common Controller, of course, that uses Ioc and DI to resolve the types needed).
  2. ViewModelB needs to set a property value in ViewModelA.

Is it bad to simply inject ViewModelA into ViewModelB via constructor injection and just set the property directly?

Or…

Should a messaging system like the EventAggregator from Prism be used to handle all communication between ViewModels?

I like the injection approach because it’s easy, but my instincts are telling me I’m missing something. I call on your collective wisdom to help fill in my blind spot.


Solution

  • I suggest you read this question (and my answer) since it's similar, but not exactly your problem. It does deal with communication of properties between parent/child ViewModel objects.

    Let's look at a basic example:

    • ViewModelA is the parent and has to present the Sum of some property on B
    • ViewModelB is the child and has a property that needs summing

    So the user makes a request to edit the property on B and the request succeeds, so B presumably changes the value of its property and fires a PropertyChanged event.

    ViewModelA could subscribe to the events on all children, but having gone down that path, I don't like it. When children are added and removed, you have a lot of bookkeeping to do.

    Injecting A into B is cleaner, but you still have a lot of bookkeeping to do. What if you have a "Clear Children" action on A? You have to remember to properly get rid of the parent relationship from B to A in all cases. Still it's better than events in my opinion because it's more explicit.

    Personally I like the messaging idea. I'm more familiar with MVVM Light's messenger than Prism, but it's the same idea... a global message bus. At any time, any B can say "I changed my property!" and then A listens for the notification and does the computation itself. I think this is your cleanest solution with much less bookkeeping.