Thierry Thierry - 17 days ago 15
C# Question

Clarification and naming convention for Model and ViewModel in MVVM

I'm confused in what should be a model or a view model and how should these be named.

For simplicity sake, I'll leave the

INotifyPropertyChange
out of it.

The following class is clearly a model:

class CountryModel
{
public string Name { get; set; }
public string Location { get; set; }
}


What you mostly see on the web is that a view model would be defined as follows:

class CountryViewModel
{
public CountryViewModel
{
// initialize data (not ideal place, I know, but keeping it simple!)
}

public ObservableCollection<CountryModel> Countries
{
private get;
set;
}
}


Why isn't the above a model of
Countries
, i.e.
CountriesModel
, for example? Why is it considered a view model?

Should that technically be the case? Should we have another class for the view model, then?

class CountryViewModel
{
private ObservableCollection<CountryModel> _countries = new ....;

public CountryViewModel
{

}

public ObservableCollection<CountryModel> Countries
{
private get { return _countries ?? _countries = LoadCountries(); }
set { _countries = value; }
}

private ObservableCollection<CountryModel> LoadCountries()
{
ObservableCollection<CountryModel> countries = new ...;
foreach (CountryModel country in CountriesModel)
{
countries.add(country);
}
return countries;
}
}


Is the above making sense? I just don't understand why it seems to be a standard and why you would call
CountriesViewModel
when to me it should be
CountriesModel
and a
CountryViewModel
should be created accessing the data from the
CountriesModel
.

Also, if you stick to what's on the web, i.e.
CountryModel
and
CountryViewModel
that contains an observable collection of
CountryModel
, then how would you deal with countries containing each a list of cities? I would have a
CityModel
as a POCO and then for the list of cities, I would create a
CityViewModel
having an observable collection of
CityModel
.

But then what? Am I supposed to make the
CityViewModel
part of my
CountryModel
? That doesn't seem right at all! Maybe it is and someone could clarify that. This is where I get confused even more as I would have created a
CountryModel
with properties
Name
,
Location
and a property of type
List<CityModel>
, but how do I represent this correctly in MVVM?

How to define this correctly? Especially the part where you have a list of objects and each of those objects contains another list. Which is a model, a view model and how do I handle the list inside my model?

Answer

Typically, people make a view model for every view they have in their system. The purpose of the view model is to facilitate the view's data. View models are usually a flattened version of their domain model counterparts, but this can seem confusing when you have flat domain models that are really just data transfer objects (DTOs). Do not be afraid to have view models that closely resemble a domain model; they are different abstractions of the data intended to live and work in different areas/layers of your application.

As for your questions/examples, if you had a view in your application that represented countries and cities in a hierarchical nature then yes it would be perfectly acceptable to have a CountryViewModel that was composed of a CityViewModel, along with any other view models that helped comprise the data for that particular view. It is also possible to use inheritance in view models so that you could have base view model class that held error information for anything that went wrong, such as issues retrieving the data, issues mapping the data or issues validating the data.

Since you will generally want to have a view model per view in your application, you many times end up with a set of view models that match the CRUD operations for your domain model object. For instance, say you have an Account domain model, then you would probably have a CreateAccountViewModel, DisplayAccountViewModel, DeleteAccountViewModel and UpdateAccountViewModel.

Many people get concerned with duplication in their code and think that it is wrong to have a domain model and view model that are almost identical in structure and data types, but remember that they serve very different purposes; domain models exist to facilitate the data for the problem space you are working in, while view models exist to facilitate the data for displaying information to the user in a view.

It is also not unheard of to have a data model class in a data-access layer that differs from the domain model, but mirrors the structure of the data being retrieved from a database table. This is how you can use a micro-ORM like Dapper. Instead of writing the ADO.NET DataReader mapping logic, you create a data model class that matches the column names in the query you use to retrieve the data from the database and then use that class as the object to "dump" the data into. From there you could have mapping logic to build a domain model class that gets passed back down the layers of your application.

Comments