-1

I don't think these are duplicates:

I am creating a local application. The data entered by the user is either going to be stored in local files or in a locally hosted database. I am trying to figure out how I should structure the saving of the data. If it's relevant, I want the data to save only when the user requests a save (i.e. I don't want to be writing to a DB/file every time the data stored in the Model is changed).

[Side note it is recommended that the V, VM, and M are all kept in sync, yes? You don't want to only occasionally be updating the Model, correct?]

Going by the definitions in this article and this question the Model contains the business/application logic and the data and the ViewModel contains the presentation logic and translates the data from the Model into a presentable form. Managing (e.g. saving) does not really seem to fit very into either of these categories.

Question 1. Should the functionality for saving (and for that matter loading the data on application startup) be but in the ViewModel, the Model or some other entity, call it a Controller for lack of a better word.

Question 2. I am knew to both WPF and MVVM and am very interested in (/unsure about) application structure/architecture. How should the View notify the ViewModel/Model/Controller that the user has requested a save? Are Commands the right tool (I am not familiar with commands either I have just read about them a little). If a Controller is a good option what structure would it have, which MVVM components would it need to be aware of (or would it be blind to all of them). Where would it be constructed (maybe in App.xaml.cs?) or would it be a static object?

Commonaught
  • 340
  • 5
  • 11
  • Typically I view the model as a simple data object with limited or no logic at all and the logic for saving/loading model objects (or other operations on models) really belong in one or more services. The models and services generally make up the domain layer (or business layer) but I think often the term Model gets used interchangeably between actual data models (or data transfer objects aka DTOs) and the domain model/layer. – coding.monkey Aug 24 '21 at 23:50
  • View Models can bring the services and data models by consuming services through dependency injection. These services typically have a well defined interface and it's the interface that is passed into the view model or resolved via a dependency injection container. Injecting the interface is important for unit testing and abstracting away concrete implementations from the view model. For example, you might have a IModelService that has the logic for saving and loading data models to files. Setting up the DI container is usually done as the application is starting in the App.xaml.cs – coding.monkey Aug 24 '21 at 23:54
  • Well defined interfaces for services also provides flexibility because different concrete implementations can be passed in for different behaviors. For example, you could have a service that handles loading/saving data to files, another implementation that handles saving/loading to a DB, and perhaps another that uses web APIs instead. The point is that the view model doesn't know or care what the service is doing really - all it knows is to call Save()/Load(). :) – coding.monkey Aug 24 '21 at 23:57
  • @/coding.monkey sounds like I need to learn about dependency injection and making my own services. – Commonaught Aug 25 '21 at 01:41
  • The model is however CRUD for your data is exposed. Some sort of a class that serialises and deserialises data maybe. You need to get data from that and save data via it. That often involves some sort of DTO. This should be separate from a viewmodel. The viewmodel has to implement inpc and might adapt data and commands to and from the view. Often automapper is used to copy data to and from viewmodel instances. But this is done when you read or persist. You want separate for separation of concerns but also because you only want to persist validated data. – Andy Aug 25 '21 at 10:04
  • 2) MVVM does not define a Controller (that'S why there is no 'C' in MVVM). Usually the View communicates with the View Model using data binding or commanding. – BionicCode Aug 25 '21 at 11:48
  • [Commanding Overview](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/commanding-overview?view=netframeworkdesktop-4.8), [The Model-View-ViewModel Pattern](https://learn.microsoft.com/en-us/xamarin/xamarin-forms/enterprise-application-patterns/mvvm) – BionicCode Aug 25 '21 at 11:51
  • 1) The pattern defines that data management belongs to the Model component. View Model component converts/presents data from Model to the View and also sends modified/collected data (by the View) back to the Model. The Model processes and persists this data. View interacts with the user and displays/modifies/collects data and communicates with the View Model using data binding and commanding. Having the View listening events of the View Model is also an option. – BionicCode Aug 25 '21 at 11:56
  • You said *"Managing (e.g. saving) does not really seem to fit very into either of these categories."*. But that's not true. Your referenced article and its definition of the Model component: *"that encapsulates the app's data"* - this also includes the corresponding logic like read/write operations from/to a data sink. This is also emphasized with this statement: *"Model classes are typically used in conjunction with services or repositories that encapsulate data access and caching."* – BionicCode Aug 25 '21 at 11:56

1 Answers1

0

It seems to me that you are a little confused about the terminology from different patterns.

If we consider OOP patterns of APPLICATIONS (MVC, MVP, MVVM), then in them View is the GUI, and the Model is a layer working with real data, processing it, containing Business Logic.
This layer is universal and independent of the type of GUI used, and even of its presence or absence.
From the point of view of these patterns, any action with real data (including saving it) is a function of the Model.
But the Model itself is not one specific type, but a whole Application layer, which can even be implemented separately within the other Application (for example, a service running in the background without any GUI).
Therefore, the Model itself can be implemented in the form of many additional types: a core with Business Logic (it is under it that they most often mean the Model in the narrow sense of the term), Repository, services, etc.

A little confusion here is introduced by the fact that in some patterns (ADO, EF, etc.) the term Model is also used to denote some entities.
Let's say this is often used to denote the type EF reflecting a record in the database table.
From the point of view of MVC / MVP / MVVM patterns, these are not models, but entities: Database Entity, EF Entity, Business Entity, etc.

The model provides consumers not with real data (that is, not Business Entities), but already some kind of reflection of them (very often these are immutable DTOs).

Therefore, the answer to your question: Saving data is a function that MUST be implemented only in the Model. "Inside itself" the Model can deligate this to some of its separate parts, for example, the Repository.

ViewModel is also a MODEL. But it is designed to work with a certain type of View, so it must take into account the peculiarities of this type of View, its requirements.
For example, a ViewModel for WPF (this is almost always the case), must provide the Data necessary for the View in its properties, notify about a change in its state using the INotifyPropertyChanged, INotifyCollectionChanged, Icommand, IDataErrorInfo interfaces and other requirements.
In this case, the "real" Model serves as the data provider for the ViewModel. Therefore, the ViewModel does not work with real data, but with its abstract reflection.
And "knowledge" about real data (including how and where to store it) is not available for the ViewModel.

Since you need to provide the user in the GUI with a way to explicitly save data, this must be implemented as a command in the ViewModel, which calls the required Model method in its executing method.
In this case, the Model means the entire corresponding layer.
That is, it is not necessarily the main part of the Business Logic Model.
It can be, for example, some kind of service that is part of the Model layer.

It should be understood that very often in practice deviate from the ideal MVVM implementation. Therefore, in practice, you can often see leakage in the ViewModel of non-specific functionality, both from the View side and from the Model side.
Even if you have to do this to simplify the implementation, then you must clearly understand that this is a deviation from MVVM, and although you implement some specific function in the ViewModel, in fact it is a function of the Model (or View).

On your second question.
The MVVM pattern is hierarchical: the top level is View, below it is the ViewModel, and at the bottom level is Model.
In such a hierarchical structure, the overlying layer possesses knowledge only about the underlying one.
That is, the View is "familiar" only with the ViewModel, and the ViewModel only with the Model.
And the Model, in general, does not "know" anyone.
The application itself (the App class) is not part of the MVVM pattern. It is located, as it were, above all the layers and therefore "knows about everyone."
Usually, in application (maybe not in the App class, but at this level), layers are initialized, dependencies are created and injected, and other tasks are common for the entire application.

"Notice" in .Net refers to events.
To receive notifications from someone, you need to subscribe to the event of this object.
And for this you need to be "familiar" with it, that is, to have a link to it.
But the underlying layers are not familiar with the overlying ones.
Therefore, neither the ViewModel, let alone the Model, can subscribe to View events.

But there is no need for such a notice for the View.
Notifications are needed where the object wants to provide information about its change, but it does not know who needs it.
Those who want to receive such information subscribe to the events of the object themselves.

But the View "knows" who it wants to notify - this is the ViewModel.
Therefore, the View simply calls the required ViewModel method and passes the required parameters to it.
This is most commonly done in WPF by binding to a command-property in the ViewModel.

P.S. The article "The Model-View-ViewModel Pattern" presents a point of view that is very close to the one I have stated here, but in much more detail.
You may find it helpful to read it.

Quoting from this article:

Model
Model classes are non-visual classes that encapsulate the app's data. Therefore, the model can be thought of as representing the app's domain model, which usually includes a data model along with business and validation logic. Examples of model objects include data transfer objects (DTOs), Plain Old CLR Objects (POCOs), and generated entity and proxy objects.
Model classes are typically used in conjunction with services or repositories that encapsulate data access and caching.

EldHasp
  • 6,079
  • 2
  • 9
  • 24
  • 2
    I found your terms about real and not real data quite confusing. The View Model simply presents data to the View. But is not responsible to control persistence. It does not know where data is read from and where it is written to. But it deals with real data of course. You seem to confuse data with data entities. – BionicCode Aug 25 '21 at 11:26
  • 1
    Also describing MVVM as hierarchical (with the View as the root) is not correct and will bring up wrong associations. When MVVM describes the components of your application, then the Model is the foundation - not the View. The Model defines the application - it would be the foundation of a pyramid or the root of a tree. You should view MVVM as a pattern that describes the responsibilities and the uni-directional relationship of components that build the application and not as a hierarchical tree construct. – BionicCode Aug 25 '21 at 11:26
  • 1
    Also in terms of architecture MVVM does not describe a layered architecture. The layered architecture exists side-to-side with the MVVM application component structure. MVVM exists with the goal to decouple the view from the business logic. You can design the Model component based on a layer architecture like business layer and persistence layer. From an acrchitectural point of view the Model is not a layer, but an application level component that can be designed using layered architecture patterns. – BionicCode Aug 25 '21 at 11:26
  • @BionicCode, I am very sorry, but I did not at all pursue the goal of explaining something to you. I think you understand everything perfectly well without my explanations. My explanation is intended for the TS, to the best of my understanding of his knowledge. For a complete explanation of all the nuances, you need to write a thick textbook. I have no such goal. It is more important for me to answer here and now so that TC would benefit from this answer for his practice at the moment. – EldHasp Aug 25 '21 at 18:24
  • @Commonaught, I supplemented my answer with a link to a simple MVVM article. Read it. I think this will be useful to you. – EldHasp Aug 25 '21 at 18:26
  • @EldHasp I actually linked that article in my question lol. I haven't read the whole thing but I will keep looking through it. – Commonaught Aug 26 '21 at 15:51