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.
Related
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.
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.
I've been using MVVM for a while now with WPF. And i've learnt a lot over the course of development (going from never using it, to having a couple of applications developed in it)
However, recently I had some comments directed at the code which made me wonder if i'm doing things the right way. My current setup works (roughly) like this:
Model - Responsible for storing the data, data validation using
IDataErrorInfo and dirty tracking
ViewModel - Responsible for getting the data (from a repository like
pattern) and formatting it for a view's consumption (things like
filtering, ordering) also responsible for command handling from the
view (save, load, filter changes etc)
View - The usual UI stuff
Now it was mentioned to me that i should NEVER have business logic inside the model, and that the model should be as thin as possible, the viewmodel should be responsible for handling things such as data validation and dirty tracking.
I've seen comments and criticism on both sides of this, with people against and for putting logic in the model, What i have yet to see is any actual reasons for these sweeping statements. So id love to know if there is an actual reason i should be refactoring my setup.
Also, given that i do move the logic to the viewmodel, I can see the need for having multiple viewmodels where i currently have a single, for example:
Person - Model
PersonViewModel - Handles the dirty tracking, data validation etc
PersonsViewModel - Handles getting a collection of PersonViewModels,
filtering etc
PersonsView - The UI
This seems a little redundant, but perhaps i'm misunderstanding something. What I'm really looking for is some actual reasons for doing this one way or another, or if this is another argument like the use of code-behind in MVVM (pure opinion with little reasons etc)
High level description of MVVM:
View: User Interface
Model: Business logic and data (e.g Domain Model+Repositories, or Transaction Script+POCO entities, etc)
ViewModel: Data exposted to view in such form, that is easily consumable from view. Wikipedia's definition says: The view model is an abstraction of the view that exposes public properties and commands.
I like the Practical MVVM Manifesto (archived version) principes: Simplicity, Blendability, Designability, Testability.
This is very high level and abstract description and that's why you may find a lot of variations of MVVM. Whatever mvvm style you choose, keep in mind the responsibilities and principles and you should be ok. Try to avoid complexity. MVVM is not a silverbullet and you cannot cover all scenarios with single design pattern. One mvvm implementation may be suitable for one application but not for another. I, for example, build my mvvm architecture from scratch for each new project to ensure the best fit
When is comes to responsibilities:
Take validation as an example:
validation logic that password and repeat password inputs should be equal is clearly presentation logic and should be present in viewmodel. On the other side, there may be business rule, that password must contain at least one special character. This logic should reside in Model, however you may expose it in viewmodel to be easily consumable from view. It's a business logic, but you may need to present it somehow.
if you have application that only uses webservice to retrieve and store then your model will be probably just the data access components.
Here is couple of resources:
Wikipedia: https://en.wikipedia.org/wiki/Model_View_ViewModel.
MVVM is variation of Martin Fowler's MVP pattern, you may find it useful as well: http://martinfowler.com/eaaDev/PresentationModel.html
MSDN (Pattern and practices): https://msdn.microsoft.com/en-us/library/hh848246.aspx
I like to think of the Model layer as anything that has nothing to do with how the app is hosted (i.e. independent of WPF). It is one or more dlls that represent the business domain and the operations that need to be performed in it. If it would make sense to take theses same dlls and use them in a web application, windows service e.t.c then it is usually a sign that the split between Model and ViewModel is appropriate.
There's no simple answer to your question. The simplest answer is that the model and view model should contain the code that you should unit test. The separation between model and view model is a little less distinct. I like to keep the model as simple as possible and limit it to whatever is exchanged with the server tier. The view model should encapsulate the model, and provide any addition functionality (both business logic and abstract presentation logic) so that you can keep the presentation layer as simple as possible (declarative, in the case of WPF XAML).
I see it this way:
Model - Object that can be passed around. A Common type between different layers for communication.
ViewModel - Specifically created for Views. This should contain UI logic, for example, Data Annotations etc will go here. You might also call your web service methods here (assuming your actual business logic sits in a facade layer, or your database logic sits in a different layer/project) to populate the Views, dropdowns etc. You might end up with multiples of these per view, depending on your design.
View - UI Only.
I am not afraid to put external calls in the ViewModel
I have an MVC ASP.NET project and I currently use a static ViewModelHelper class which has several methods (1 for each view model) that take in certain parameters and model objects and generate the view model objects for me to return to my views from my controllers. They are currently all static and the class as a whole is stateless, I just use it when I want to instantiate an instance of the view models because some of the data requires rather complex logic.
Would these methods be better off as constructors in the View Model classes? My understanding was it is better not to have any logic in the View Models, but I could be wrong. Or is there perhaps a design pattern I should be using here to help me create these View Models?
It's a question of your project's architecture and design how your ViewModels should look like and where/how they should be initialized. It seems that right now your ViewModels are DTOs and you initialize them with a factory approach. That is fine, but I'd suggest to actually embrace the abstract factory pattern then and make sure that the factory implementation doesn't get overloaded with unrelated responsibilities. That is an inherit problem of "utility" classes that should make every developer wary.
On the other hand, view-related initialization logic, e.g. populating select lists, can very well be located in the ViewModels themselves. In that case you should be wary of duplication.
Another possible approach would be to utilize a builder pattern.
Either way can be a clean solution if you use it exclusively and not mix and match. And as long as you keep it clean, of course. ;)
Without having seen that rather complex logic, I'd suggest you check why the initialization logic is that complex to begin with, though. And if it really has to be. Maybe some business logic snuck in there?
Your ViewModels should be just DTOs, classes with properties only. No logic. Put logic in other classes (services or full business logic, depends) and have them populate the ViewModel.
I'm aware to the fact that this answer seems very short relative to the substantial design consideration, but that's the core of it. For reasoning etc. please have a look at some full-fledge ASP.NET MVC solutions that demonstrate it, like https://prodinner.codeplex.com/.
I am using MVP to structure a project in C#. I previously had a IModel interface which contained CRUD operations, but have since split it into a number of Model interfaces (e.g. INotebookModel, ICategoryModel, IItemModel etc.) which each contain CRUD operations.
Would it be better to have an overall model which has CRUD methods that delegate to the appropriate specific models (e.g. create(String type)) or just holds references to each specific model in the presenter?
If having multiple models is a bad way to do it, how can I pass down the appropriate parameters so the model objects can be created/updated? As each object requires different information.
Having different models is not a bad way to do it.
This will surely make your design more complex but certainly increase your app's maintainability.
If you're building an app that needs to be evolutionary in future upgrades, then seperate your Model into several Models. This will help you in case you want to add a different entity into your app.
Maybe your books will be assigned to persons, then you will add a IPersonModel interface and the three other interfaces (INotebookModel, ICategoryModel, IItemModel) will remain intact.
However, if your application is simple and you want to favour rapid developement just centralize your model into one big Model. But be careful, if your app gets bigger, this model gets more and more complex since it will handle nearly all the app's responsabilities and you will have to explode it into many several ones.
So seperate your responsabilities, it is one of the SOLIDs. You can go further and take a look at this: http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)