2
votes

In my WPF MVVM application I use dependency injection container. When I want to retrieve some data from my Model, I use an asynchronous interface to query the Model and fill the ObservableCollection in my ViewModel (I understood it thanks to the answers to my previous question).

I'm looking for a best solution to handle a following situation. There is a collection of objects I'm retrieving asynchronously from my Model. I want to use the same data to build observable collections in two different ViewModels, as I want to display that data in two different windows. The Model domain objects are going to be wrapped in different ViewModel objects as the wrappers needs to prepare the domain objects to be displayed. I don't want to retrieve data from the Model separately in each ViewModel, but to do it once, as it might be a time-consuming operation.

I've seen a few examples and everywhere a single ViewModel is responsible for retrieving data from the Model service. What should I do to use the once retrieved data in more than one ViewModel?

I think that I should introduce another layer of abstraction between my Model and ViewModels that will handle the caching of retrieved data and every ViewModel that wishes to utilize this data will have the dependency to this layer.

Is this a good idea?

3

3 Answers

2
votes

That missing link would be a service as referenced within Prism.

The model classes are typically used in conjunction with a service or repository that encapsulates data access and caching.

You'll note in the previous question that I am making use of a service within that ViewModel.

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;
   }

}

Note the IScriptService being injected into the ScriptRepositoryViewModel. That service actually implements caching and varying logic so that whoever polls for the Scripts will get a cached copy or perhaps a fresh copy; the consumer doesn't need to care.

In your instance with your two ViewModels needing the same data you could follow the same pattern of injecting a service into each ViewModel. When the ViewModel calls the service to retrieve the data you can implement logic to not fetch the data from the back end unless it has been stale for 10 minutes or whatever behavior you so desire. It has been abstracted at that point and you are free to do what you need; allowing N ViewModels to consume the data form a central location without un-needed load.

0
votes

Yes you have to introduce another layer, irrespective of caching or not in my applications ViewModels are used for sole purpose of binding to Views and they don't contain any logic of retrieving data from Business (Service) layer

0
votes

Use RegionManager["nameRegion"].context, the ViewModel is the context of the View, that yo can share with other ViewModels