Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 655
Chris Swain Avatar asked Oct 13 '22 17:10

Chris Swain


3 Answers

I consider it a code smell if you need two-way references. Often you can replace one of the references with an event.

Let ViewModelB raise an event that ViewModelA subscribes to. A complete messaging system like the one found in Prism is certainly an option, but in your scenario it sounds like a 'normal' event will do just fine.

like image 152
Mark Seemann Avatar answered Oct 28 '22 19:10

Mark Seemann


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.

like image 42
Scott Whitlock Avatar answered Oct 28 '22 21:10

Scott Whitlock


I suggest using a much lighter dedicated Messaging solution called "Light Message Bus". It is not part of any yet another ;-) MVVM framework, but independent component. And I got it working in no time in less than 3 minutes.

like image 38
AnjumSKhan Avatar answered Oct 28 '22 21:10

AnjumSKhan