2

I’m in the process of improving my understanding of the best practices of MVVM / dependency injection, and something that seems fundamental is still quite unclear.

Scenario:

  1. The model (composed per the Composition Root pattern) consists of a DI object graph similar to the following:

Object graph

  1. The constituent parts of the graph (A1, B1, etc.) have state.

  2. The state of the constituent parts (A1.StateA1, B1.StateB1, etc.) doesn’t just serve as dependencies for other objects in the graph, but also needs to appear on a view.

Questions:

  • How to properly expose this fragmented/nested state to a viewmodel?

If my understanding is correct, the model doesn't supposed to cater to any kind of visualization of the state – it is the responsibility of the viewmodel to format the data according to the view's requirements.

Does this mean that the viewmodel should know about the specifics of the model composition, and directly reference e.g. B2.StateB2 (or even A1.A2.B1.B2.StateB2)?

  • Or, is it a good practice to try to separate the state and the behavior, and store all state in a flat object that is easy to consume by the viewmodel?

The specifics of what I'm trying to do:

The concrete app I'm designing serves as a simple extension to a business app (a localization software) to make up for some missing functionality that is specifically useful in a large localization project. My app's model is getting the data from multiple sources:

  • One source is tracking the target app's process and window status by subscribing to Process.HasExited and AddAutomationFocusChangedEventHandler.
  • Another source is reading the private memory of the target process by PInvokes at a timed regular interval.
  • Yet another two sources are XML (XLIFF to be exact) files where I need to look up nodes based on the last value I've read from the target process' memory. This lookup produces a list of strings related to the active localization unit in the localization software – this is the main information the app view needs to convey.

I admit that the app is a bit hacky, but there is around 20% end user productivity difference at stake. :)

The main viewmodel is rather simple, only a few controls, including a WebBrowser that I'm filling with assembled and formatted HTML data. The critical point here is to have the data up to date all the time, but my model objects implement INotifyPropertyChanged for that purpose.

Leaky
  • 3,088
  • 2
  • 26
  • 35
  • 1
    If you follow the [Law of Demeter](https://en.wikipedia.org/wiki/Law_of_Demeter) then you will not end up with `A1.A2.B1.B2.StateB2` which helps you when you need expose something to the View. And I think this question is more suitable for [Software Engineering](http://softwareengineering.stackexchange.com/questions). – Fabio Feb 21 '17 at 09:47

1 Answers1

1

Or, is it a good practice to try to separate the state and the behavior, and store all state in a flat object that is easy to consume by the viewmodel?

If you're referring to the state that is shown by the app using views, then yes it should be flattened, or better yet stored in the ViewModel itself.

Where is the model gettings it's data? Could you store that data directly in the ViewModels, rather than creating a model just for holding data between the source and the ViewModel?

Usually in MVVM development the Composition Root approach to IoC is done with the ViewModels, not the models.

Cameron MacFarland
  • 70,676
  • 20
  • 104
  • 133
  • I've added the description of the concrete app I'm working on to the end of the question. Yes, from what I can see, I could store the data directly in the ViewModel. Pulling all the data together in the ViewModel seems to make sense, and I already have interfaces for the pieces of data that I can use as an abstraction layer between the data consumer and concrete data provider classes. I was just unsure if the ViewModel should have that much knowledge of the model structure. Maybe I overcomplicated it... But if you have anything else to add or correct, I'd happy to read. :) – Leaky Feb 21 '17 at 13:56