ceebreenk
ceebreenk

Reputation: 1029

Proper way to communicate/pass values between viewmodels?

I know there's a lot of questions on the topic and I understand how to do it but I need some help on the design of my architecture. I'm using the Simple MVVM Toolkit.

Architecture

I'm using Messaging to pass data between the VMs. The validation and prompts (using dialogs) of the PageValues data is controlled in my ManageVM. I placed it here as I feel my ManageVM should handle all 'management' like setting the client and store. Setting the actual values is done by sending a message to the ShellVM that handles this.

The ShellVM handles the CRUD of the PageValues. So in other words, if any VM gets or sets a global/shell-wide property, it does so by means of messaging to the ShellVM. The ShellVM then sends the message/result back to whichever VM requested it.

Question

This feels very spaghetti-like. I've got a ManageVM that does the loading and validations on PageValues that are actually CRUD'ed in the ShellVM.

Am I on the right track or is there any other suggestion I can try to make this feel a bit cleaner?

Thanks for reading.

Edit

What I'm trying to achieve is to have a container that holds values (ie client and store) that could be accessible from multiple VMs. A bonus is to have each page's/view's values in this container too. Then on showing of the view, it will grab its values from the container and populate the view.

Upvotes: 2

Views: 678

Answers (2)

Jimmy
Jimmy

Reputation: 3264

You said

if any VM gets or sets a global/shell-wide property, it does so by means of messaging to the ShellVM

I propose an interface based approach instead of message passing for this purpose. ViewModels passing messages is for view models to communicate,not for setting a global state. If there is a global state of the application,it is better handled through a dedicated service, IMO.

public interface IApplicationService
{
    //your applcation methods here
}

public class ApplicationService:IApplicationService
{
}

public class ManageVM
{
    public  ManageVM(IApplicationService){}
}

public class ShellVM
{
    public ShellVM(IApplicationService){}
}

public class SomeOtherVM
{
    public SomeOtherVM(IApplicationService){}
}

Upvotes: 2

GazTheDestroyer
GazTheDestroyer

Reputation: 21241

Yes, this does sound rather messy. You need to try and isolate areas of functionality into their own VMs so they are not dependent on one another.

One of the tricks I use to do this is to try and imagine that I suddenly need to copy a blob of functionality (say one of your pageviews) into another application. How easy would it be? Would it be a case of just copying one VM and injecting a few dependencies? Or is the VM impossibly coupled to the rest of the app?

It's a bit difficult to give advice without knowing exactly what your app is doing, but really you want each PageVM to be in charge of it's own validation, and CRUD. Or, if the data is shared between many pages, then you need to pass in some kind of repository than the PageVMs can query for data. If validation logic is specific to some data, then put it on the model itself and just leave the presentation of that validation to the VM.

For global settings, I tend to pass around a settings object rather than using messaging.

Have a read up on inversion of control, and dependency injection. These can help you to keep objects loosely coupled because you can see exactly what other things your object is depending upon by looking at the constructor. If you are passing in half the application then it can serve as a warning alarm to try and reduce the coupling.

Upvotes: 0

Related Questions