MVVM: The Link Between Model and ViewModels

I am developing a WPF application using the MVVM pattern. I am using the MVVM Light library, and I am also trying to use the dependency injector (I am considering Ninject and Unity).

I read a lot of blog articles, and I'm pretty confused about the β€œright” way my classes communicate with each other. In particular, I do not know when to use Injection Dependency and when to rely on a mediation template.

Let's look at an example. I have a ViewModel, let's call it DataViewModel and a Data class that provides some kind of data. How to better communicate between them:

but. Introduce dependency with DataViewModel with IData interface? Thus, Data will not necessarily rely on Messenger, but it will have to provide an event if the data is changed and the ViewModel will have to subscribe to it.

Q. Rely on an intermediary template (implemented in MVVM Light as Messenger) and send messages between Model and ViewModel? Thus, there is no need to use Injection Dependency at all, because the whole communication will be based on messages.

Also, should my ViewModels inject dependencies into other ViewModels, or would it be better to just rely on Messenger? If the first, would you need to define a separate interface for each ViewModel? I think that defining an interface for each virtual machine will be additional work, but maybe it's worth it.

+6
dependency-injection mediator wpf mvvm-light
source share
2 answers

Typically, the ViewModel goes to the service (what is its name Prism) to obtain the necessary data. This service is ported to the ViewModel via the DI (Constructor Injection), although you can follow this other path through the ServiceLocator.

Therefore, your ViewModel will refer to a service that will abstract the retrieval of your data. Data can come from a DB file, XML, which knows ... there is an abstraction. Thus, for your case with IData, a reference to this type will occur at some point in the ViewModel, but not through any of the DIs. If your IoC framework allows (Prism), you create a mapping of interface types to specific types, and then extract those types through your container; this is the case with Oneness.

Here is a brief example ... Scripts are attached to the view, and the ViewModel is entered into the view. Note the use of IScriptService to retrieve data. The returned data is a set of IScript types, however, we never officially introduced this type in the ViewModel, because we do not care about the type as a single object, which we care about the type in the scale of greatness.

public ScriptRepositoryViewModel(IUnityContainer container, IScriptService scriptService, IEventAggregator eventAggregator) { _container = container; _scriptService = scriptService; _eventAggregator = eventAggregator; } public ICollectionView Scripts { get { if (_view == null) { _view = CollectionViewSource.GetDefaultView(_scriptService.Scripts); _view.Filter = Filter; } return _view; } } 

When you go to the view, the same case may be there, the view will be introduced via DI (inline constructor) using the ViewModel. I would not make other ViewModels depend on each other, isolate them. If you begin to see the need for a connection, take a look at the data that you are trying to transfer, most often that this data should be abstracted further and not tied to any ViewModel.

+4
source share

There is more than one good solution to your problem,

I suggest you use one interface in your data models, put it in the base class, this interface will allow your data objects to communicate with the outside world.

For presentation models, it is not data that is entered, but an interface that can retrieve data for you, the data will expose events that vm can register for them after it receives them.

The data oject does not need to know who holds it, the view model knows what data it holds, but I do not recommend entering this data because of problems with flexibility.

+1
source share

All Articles