Should I create ViewModel for each View? [duplicate] - c#

This question already has answers here:
ASP.NET MVC Model vs ViewModel
(5 answers)
Closed 3 years ago.
I'm new in programming, maybe my question is stupid, but I try to understand this concept right. In my small asp.net core web application I have entity classes, for example, product, a unit of measure for these products. I store them in a database, using entity framework. My entities are very simple and I pass them straight to the View (pulling them off a repository). My mentor says that in big serious projects people never do like this and it's not right at all, that in a well-written code View layer shouldn't know about entities and data layers at all, they should be totally independent. Does it mean that I should create ViewModel class for each View, even if they equal to my Entity classes? What are the best practices on this topic?

You most definitely shouldn't. These kinds of global rules rarely apply.
Let's see about the MVVM pattern:
A criticism of the pattern comes from MVVM creator John Gossman himself,[12] who points out that the overhead in implementing MVVM is "overkill" for simple UI operations.
I think that answers your question on creating a view model for everything.
If the model does not fit the view or is complicated enough then you can use ViewModel.
Your mentor's idea (I guess) is that you should always think in terms of Domain objects instead of database objects. But as you'll see in any example, there is no reason not to use a POCO object straight out of the db if it fits the view.

Though not a rule but it is practiced as standard in many projects. Entity objects are not directly passed on to your view. Please refer the link.
For instance, you might want to hide some properties in the view. In such case if there is an intermediate class like Data Transfer Objects defined, client will be exposed only to the DTO class and not your DB class objects.

Related

project design, am I understanding this correctly

I'm a software developer but always worked on "small" projects/solutions.
Now I'm trying to create an application from scratch on my own, just to stay in touch with new developments and learn new stuff. I'm trying to use everything I've never used before.
So basically that means I'm developing a c# application, using EF core 2.1 and SQL Server.
I've read a lot of articles online and I learned A LOT already. But I'm still confused because everyday I find a new article using a different approach.
I would like the opinion of some other developers on what I've got so far.
First of all I'm used to WinForms so for now I'll use that as my UI. Just because I can get fast results with it. Afterwards I'll try using ASP.NET Core.
I also want to be able to use an other UI and still be able to use the rest of my solution.
I have several projects in my solution:
1. Data: EF Context, DbSets, Migrations
2. Models: EF models, used in EF Context (nothing more then POCO's)
3. DTO: Objects exposed to the UI (again, classes and properties, nothing more)
4. Mapper: "DTO to Model" and "Model to DTO"
5. Services: static classes and static methods/functions using all the above, containing the logic. for example GetCustomer uses the EF context class to read the database, gets the model, maps it to a DTO and returns it.
6. UI: binds to the DTO objects and uses the services for every user "action".
That's it, in a nutshell. But am I on the right track?
I've read a lot about IoC but I'm not there yet, but as far as I understand that has "nothing" to do with the above.
I do have 1 specific question: In WinForms there is validation using the IDataErrorInfo interface and for binding I need the INotifyPropertyChanged logic. Where does this belong? I would say in my DTOs but some say a DTO "can't have" any logic.
I'm sorry for the long "question" but I'll appreciate any input to make sure I understand all of this correctly.
A DTO is usually not intended for presentation. It is intended to send raw data, so they're usually dumb objects and are basically just a bunch of property setters and getters.
A View Model is intended to be sent to a View and a View Model also sends back data to a controller. The ViewModel sometimes takes responsibility for presentation logic.

WPF MVVM Model how to get data

Recently, I'm learning MVVM design pattern!
In my way, I write the database function in the model, and let the viewmodel to call the database function in the model, then the viewmodel get database data and set to the viewmodel notfiypropertychanged. This is my way that I currently use!
There are some question confused me about model,
I read many article that told me model just a contain data and not more business logic, and here is my question, if model just a data container and I need to let my viewmodel to call the database then get data and set to the model, I think this way is very strange and the viewmodel code is make heavy in it. Is anybody have another method to do it? Thank you!
The Model:
"model just a contain data and not more business logic"
A model is a class which describe an entity within your domain logic. What is a domain? Starbuck's domain is coffee beverages and employees (among others), Ford's domain is cars, assembly lines, and employees. NYTimes's domain is articles, issues, supply routes, subscribers, etc, etc.
A model contains data AND logic. You can have multiple models to describe your domain.
You can place your data calls in your model, but it's more common to have helper classes, data access layers (DAL), keeping all your database calls in one place, and not spread them around.
The ViewModel:
The viewmodel sits between your domain model and your view. It's a class which expose properties of the model and represents the state of the view. The viewmodel may only exposes a subset of all the properties in the model that the UI needs to display, but it could also add properties of its own, for example; is the user in edit mode? have changes been made that needs saving? etc. The selling point with MVVM is that the UI binds to these properties on the viewmodel which is a mechanism to keep the UI up to date with changes, and this extra layer of abstraction conveniently decouples the view to any logic in your model making it more robust for code changes in either direction and testable. There's more to say on this topic, but I'll leave it to you to read on up it.
There are many good resources and info on the MVVM pattern; from blogs Model-View-ViewModel (MVVM) Explained, to Microsoft The MVVM Pattern and here on SO.
If you prefer videos, Pluralsight have good video tutorials on the MVVM pattern
Practical MVVM and WPF MVVM In Depths. They have a free 30-day trial.
"just a data container"
Such classes that only hold data to be passed around are often called Data Transfer Objects (DTO). It's common to keep them small and return collections of these from fetch database data method calls.
I've done some research in this and also found it quite confusing. First thing I like to point out is that code-patterns are abstract. Meaning that you have loads of different way to implement it / tweak it.
What most people have told me is that in "real-life" applications you usually have layers of services.
One of these services is where you get data from a database.
The Model job (in my opinion) is to give the developer knowledge about the database data and structure. One Model to one database-tabel.
It also helps in checking if the data is correct (Format checking, Type of data and so on) before sending it to the DB.
There isn't a clear answer on how to use model. I've seen loads of different implementations, and they all have been implemented for specific tasks.
Yes it might come out that some ViewModels become heavy-loaded with code and functions to perform, but then it might not be because of the code-pattern. It can be because of poor structure in code. At my work right now I've found a ViewModel that contained over 3000 lines of code (Which is WAY to much). This could easily be seperated into atleast 3 different ViewModels and Views, but as I said, poor code structure causes problem.
One thing I recommend for you to read up on is
IoC - Inversion of Control
DoP - Dependency inversion principle
DI - Dependency Injection
Hope this helps in someway explaining your question.
I read many article that told me model just a contain data and not more business logic
A model may be represented by a service, a database access layer or a business layer so there is nothing wrong with your current approach. The business logic does belong to the model.
But sometimes people tend to refer to a "child" type as a model. For example, if your view model exposes a List<Item> property, the Item class may considered to be a model. Perhaps your confusion comes from this.
This kind of classes (Item) typically implement the INotifyPropertyChanged interface to provide change notifications and are effectively rather just "nested" view models that don't contain any business logic though.
Hope that makes sense.

asp.net mvc - nearly identical ViewModels [duplicate]

This question already has answers here:
Why do we use ViewModels?
(4 answers)
Closed 5 years ago.
I am building a web application with ASP.NET MVC and am still a beginner with this technology.
I have learned that it is best practice to have a ViewModel for each View. I can understand why this is a good idea. However, in my situation it seems to create a lot of extra work.
I have a model called Rule.
It contains an Id, Title, Description, LastModifiedDate, CreatedDate, among other fields.
I have an Edit, Create and Details view for the Rule model.
According to the best practice, I have to make a ViewModel for each of the above Views. But the ViewModels for above Views are nearly identical. One of the only differences is that the Create-ViewModel has no Id, but the Details and Edit ViewModels do. Other than that, the ViewModels are nearly identical. That is, they contain the same attributes and same DataAnnotation validation fields.
Why do I think this is troublesome? Suppose I want to change some of the Data Annotations. E.g. chaneg a Maximum Length of a string attribute. If I wish to do so, I have to do so in both the Rule model, the Create ViewModel and Edit ViewModel. And likewise if I wish to add new attributes, I must do so in all the models.
Am I doing this right, or can it be simplified?
Well this is more an implementation decision rather than a best practice rule. You have to take in consideration some of the pros and cons:
Different ViewModel for each view
Modify only the ViewModel associated with the view
Flexibility
Hard to maintain with very large applications
Reuse ViewModels for different views
Modify all the ViewModels at once
Much easier to maintain
Limited flexibility
My advice would be to create the base RuleViewModel without the ID property and for the edit and details actions inherit the model and add the additional column.
It is/was never a rule to make ViewModel per View. It is all about how your architecture is. As per your requirement if you feel both the views are exact same then use same ViewModel.
IMO do not use data annotation, if possible go for Fluent Api.
For all operations: add, update, remove - you can use one view model - Rule. It is completely fine as you want to manipulate with this single object, right?
The only difference would be the displaying of multiple Rule objects - list view page, here you might want to create an extra viewmodel like RuleListViewModel which will contain a collection (IEnumerable<Rule>) of objects and maybe some more properties for filtering and so on.
It sounds like you are mixing your view models and business objects. I usually try to keep these separate as they serve different purposes.
Your business object can have CRUD methods. Your view model can have a property that exposes your object, and can in fact expose other objects if required.
Doing it this way preserves the single use rule and makes it very maintainable.
But, this really is a design choice rather than "best practice" which (let's be honest) changes with the wind.

Should there be only one ViewModel class in MVVM pattern?

I am trying to understand the MVVM pattern and there is some issue that is not clear. My Xamarin Forms application will have several Views (which is quite obvious). Must everyone of them be binded to different ModelView class? Or maybe there should be only one MV?
Yes and No
Yes -> Basically the idea is that your ViewModel should only be used by one view. If you use a ViewModel to populate an area or whatever then that ViewModel is "reused" each time that view is presented in difference places.
No -> You can use multiple models in a view model. The purpose of the view model is to abstract away the business / data layer (i.e. the model).
However, using more than one model usually indicates that the view is too large. You might want to split it into user controls (which have their own view models).
References:
With MVVM, does each UI window have its own ViewModel?
In MVVM, is every ViewModel coupled to just one Model?
I've always thought of "each View has its own VM" - the model as being a sub-set of a comprehensive design.
I will say from painful experience: do not design models in isolation based solely on the view/UI they support. Without a comprehensive model back end you will have a hard time integrating all of the pieces into a coherent, complete business model that works. Anemic classes, redundant bits, incomplete and wrong validations, same properties-different names, incompatibilities w/ existing code, gobs of hacky glue code, Programmers breaking each other's code, no re-usability, no reuse of existing classes. For us it all came to a head in a 3 month test-fail-fix tilt-a-whirl of embarrassment.

Why is INotifyPropertyChanged in both Model and ViewModel?

Almost every MVVM example I've come across has both the Model and ViewModel implementing INotifyPropertyChanged.
Other sources (ones which focus on domain modeling) seem to suggest that Models should be incredibly plain (something to do with separation of concerns?) with essentially no references to anything. Unfortunately, those sources don't use MVVM.
I'm trying to reconcile the two.
-I'm relatively new to programming and completely new to design patterns and the like so please try to go easy on me.
Edit: Let me rephrase my question. Given that the answer to the above seems to be "sometimes one and sometimes the other," WHEN should you do one and and when should you do the other. Also, how would each be implemented?
(That isn't answered in the other post. It just has them arguing with each other).
Models have to implement INotifyPropertyChanged to inform the view model that they have changed. If the model doesn't implement INotifyPropertyChanged (or another equivalent interface), then the view model is stuck using polling or other similarly inefficient methods to detect changes in the model state.
This MSDN page may be useful reading to further understand the roles of the various components that make up the MVVM pattern.
I have no idea if this is a best practice, but I have my ViewModel set up so that it is the only active entity. The Model is only directly changed when created by reading from a database (and then loaded into a ViewModel), or before saving to database (extracting from ViewModel, modifying Model properties that only matter to the database, like foreign keys).
If for some reason you desire being able to have multiple ViewModels connected to the same Model or have a need to change a Model from under a ViewModel, then you'd have a good reason to implement INotifyPropertyChanged on the Model.
I'm a relative amateur, so take what I say with a grain of salt. But this is what I've been gathering, and enforcing this separation has, I think, made my code cleaner and easier to understand and debug. So for my own projects, I'm going to try avoiding implementing INotifyPropertyChanged on my Models if I can avoid it.

Categories