Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVVM Roles for each layer

First of all I'm ashamed of myself for not being able to grasp the essence of MVVM patern after such a long struggle, and I can't help but to ask.

I searched and searched about MVVM but the layers that has been (seems to) clear to me is only the View and ViewModel layer.

So here is what I have been grasping until now with some little example, FYI I'm using MySQL queries to fetch my data:

Model

It's unclear to me what to do here. I have this class of Employee.cs:

class Employee
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Gender { get; set; }
}

My question: Should I do the queries to fetch data from MySQL database in EmployeeModel class? I read about this answer that Data Access layer is a different thing than MVVM's Model, plus I can use a repository to request a list of Employees from my Data Access layer.

Based on that answer then it should be like:

  • Employee.cs [Object properties definition],
  • EmployeeDataAccess.cs [Responsible to fetching Employee(s) data from MySQL]
  • EmployeeRepository.cs [Called by EmployeeModel to get Employee data from DA]
  • EmployeeModel.cs [Where I handle business logic like validation etc and use INotifyPropertyChanged on pretty much same properties as Employee.cs]
  • EmployeeViewModel.cs [EmployeeView's data context]
  • EmployeeView.cs [XAML]

All of that for one page of Employee list, am I doing something wrong?

Sorry for the long question, if I said something wrong I would be more than glad to fix it.

I'm really clueless at the moment, so any fresh perspective is greatly appreciated.

like image 654
Samuel Adam Avatar asked Feb 08 '13 10:02

Samuel Adam


2 Answers

Alright, let's take a look:

  • EmployeeDataAccess.cs and EmployeeRepository.cs probably (but not necessarily, look below) could be combined into one class, say 'EmployeeRepository' that fetches the data and returns your model classes.
  • Your 'EmployeeModel' is in fact a view model, so we can remove 'EmployeeViewModel' class and rename the 'EmployeeModel' to 'EmployeeViewModel'.
  • Now this point depends on what your own preference, but you can go for general repository instead of repository-per-class; in such case, you'd have one Repository class with generic CRUD methods for all data models.

Then you end up with:

  • Every data-model class gets its own view model and view (that's 3 classes per entity)
  • There's one repository, either called in the view model and then results are mapped, or you can introduce another thin layer which will be used in view model that will call the repository and do the mapping (model <==> view model) for you in one go.

Not so bad, is it? :)

Don't overthink it and don't overengineer your solution. Having three hundred different indirection layers in a simple application is pointless IMO. You can develop them as you go if the application grows and there's a justified need for separate layer.

[EDIT] I assumed, of course, that the 'model' class is an entity class at the same time; that comes with any kind of ORM, even the lightweight ones (Dapper springs to mind).

like image 64
Patryk Ćwiek Avatar answered Nov 12 '22 22:11

Patryk Ćwiek


Well you basicly got it covered. Normally i would use the N-tier model together with MVVM so in your case it would be:

  • PersonOverview (xaml)
  • PersonOverviewViewModel (viewmodel for Person Overview)
  • BcPerson (BLL contains business logic if necessary)
  • PersonRepository (DAL communicates with the database)

Also there is a DOMAIN layer witch would contain the person class. There you would use NotifyPropertyChanged over all the properties.

I agree that it is a lot of files but they have a purpose. They are used for better maintainability, good seperation of concerns and flexibility when you want to change a layer (move from MySQL to MSSQL for example).

Also a lot of plumbing can be generated, by using an OR mapper for example.

like image 37
Guldan Avatar answered Nov 12 '22 21:11

Guldan