ViewModel Do's and Don'ts - asp.net-mvc-3

I am now at the fun part of my journey in building an MVC application. I have spent the last 3 weeks researching architecture, ONION specifically, and learning about IOC/DI and such.
So my question is this:
What is the best way to implement ViewModels? I have seen some terrible examples so far.

I recommend reviewing this article which outlines different 'tactics' for handling view models.
http://blogs.msdn.com/b/simonince/archive/2010/01/26/view-models-in-asp-net-mvc.aspx
Some recommendations I can give you for view models is:
Base them directly on your view & what the user interface needs,
Prefer creating custom view models for seperate pages instead of generalizing them to be re-used across different views.
Keep them simple & flat, don't go overboard with inheritance etc.
If you are mapping from database models, adopt an existing method for mapping between your models and view models such as AutoMapper
Consider using dynamic in some cases, its more flexible and can have less friction.

Related

How strict is the mvc pattern with model and view interactions?

I am confused about how model and view can interact
I was making a simple to do app with mvc pattern and I saw an article which said you shouldn't pass the model values directly to the view, which made the project more complex than I thought (I am relatively new to programming and this is the first time I am trying out a design pattern).
But then later on I talked to someone who said that that is not true and you can send the model data directly to view, he didn't even use classes or some kind of grouping to separate the function he just put them in separate files.
I was wondering if there is a guideline that I couldn't find or we can do whatever we want as long as they are kind of separated. I would love an article or a guide to read up on as well.
Since, I am not 100% sure the context in which you are trying to apply the MVC pattern, a good generic explanation of MVC can be found in GoF's 1995 book, Design Patterns: Elements of Reusable Object Oriented Software.
In the book, they state the following.
The Model is the application object, the View is its screen
presentation, and the Controller defines the way the user interface
reacts to user input.
A more robust explanation can be found from Martin Fowler where he also
makes the case for a variation of Model View Controller that uses a Presentation Model.
If you are referring to Spring MVC then there is some magic that blurs the lines a bit. But in general, you have a controller that represents some screen or an encapsulated piece of functionality that the user (web requests) interact with. The controller serves up responses that are derived from the domain, usually via a Spring Service (i.e. #Service). The domain (Model) doesn't know anything about the View and the View may or may not know anything about the domain.
Given that, the View should be derived from the Model. But that's not always the case since sometimes how we present things to a screen is not the best logical way to model things in our domain - not to mention, the domain should be presentation agnostic. This leads into Fowler's argument for a Presentation Model, which is a model that belongs to the Presentation.
I call this a Presentation Model because it's a model that is really
designed for and thus part of the presentation layer.
Microsoft took that idea and ran with it in a variant of MVC called MVVM (Model View ViewModel).
You can read more about that in Microsoft's documentation on ASP.Net Core.
So, back to your original question of "Should you pass the model directly to the view?" If you are using MVC then the controller is what provides the interaction. But if you're really asking, "Can you bind your view directly to the model?" If your model has all the stuff you need organized how your view needs it, then sure. And if it's simple enough, maybe that's the way to go. Otherwise, you could go with something like a Presentation Model or MVVM.

How should I architect multiple instances of a View, all with very similar ViewModels using Prism and Unity

I'm using XamarinForms, and Prism for MVVM with Unity as my IoC container.
I'm refactoring a tonne of duplicate View and ViewModel code that a previous employee worked on. What they've done is essentially cut and paste a massively complex View and ViewModel. I needed to change some things in these, and had to do it 5 times because of this spaghetti code. This is basically what the view looks like:
The 5 instances of these CardViews and their different Viewmodels have a main title, 3 labels and 3 values that go with the labels. The values are retrieved using various restful calls (all using various parameters to retrieve them and processing the results of the calls too).
My question is, what patterns should I be using to simplify these 5 Views and ViewModels, preferably into only 1 file that I need to change? Roughly speaking, I think I should have a ViewModel that offers all of the text, values and functions that I require to get this remote data. But I'm scratching my head at all the different approaches that it seems are available to me (ViewModel interfaces, dependency injection, methods of registering the template view with different instances of the same ViewModel, etc).
What complicates my problem in particular is that these 5 different views are split across Prism Modules (i.e. .NET projects). I understand the need for these but they seem to just add to the problem of duplicate code that largely does the same thing. Maybe these should contain the logic for the restful calls and processing? But how would that fit in with my ViewModel/View association problem from above?
I will continue researching the best way to do this, but I just wanted to know if anyone can steer me into the best practice direction?
If you have five views that look the same and five view models that do (nearly) the same thing, drop four of each. To account for the differences in the view models perform, create services.
The BookService might implement GetTitles by querying a rest service for book titles while the DvdService queries another rest service for dvd titles. Both of them implement ITitleService. Then the UnifiedViewModel is specialized for books by passing it a BookService (preferably through constructor injection) and thus it does exactly what the BookViewModel did before. Just now you have one view model and five services where before you had five view models.

How to think about Controllers in angularjs

I'm scratching the surface with Angularjs, and thought I'd run a conceptual question past the fine folks of SO. This is a newbie question from a seasoned developer.
The application has dashboard requirements... a single page that surfaces stuff from many parts of the application. Different user types get different dashboards. We already have a legacy back end, so the first task is to build the dashboard to show many bits from it's new RESTful service layer.
I'm wondering how I should conceptually think about the controllers needed to support this?
The first question is... should they be model-centric or view-centric? In other words, should they be "view-centric" controllers that have the word "Dashboard" in them? Or should they be more focused on the model elements they represent, like "Tasks", "Contacts", "Notifications". Or should there be both where the dashboard controllers work with model-centric controllers?
The next question is... what level of granularity should the controllers represent? If view-centric "Dashboards" controllers, should they be "ManagerDashboardController" and "WorkerDashboardController"? If model-centric controllers, should there be controllers such as "LateTasks" & "OnTimeTasks" since I need to display them on different sections of the dashboard, with slightly different data?
I'm looking for tangible advice based on real-world experience and/or references to great links I've yet to find.
Here are my views from developing business applications in Angular for the past 6 months:
Role of a Controller
Initialization (loading initial data, setting options)
Exposing variables and functions to the template through the $scope
Application flow (through exposure of functions that can change state, or $watches)
I have found that, much like in traditional MVC frameworks, the controllers in an Angular app should really be super slim. Little if any business logic should be in the controllers, and should be instead be encapsulated in your models. I came to this conclusion after hearing the follow line from a presentation by Miško Hevery: "the purpose of the scope is to refer to the model and not be the model." That was the most valuable and enlightening line I got from that presentation (though I recommend to watch the whole video); that line directly resulted in me slimming down my controllers by almost 50%-70%.
For example, my company has a concept of an Order. I created a model that encapsulated all the properties of this business object, as well as its behaviours and injected them into the controllers. One business rule we had was the ability to add a Booking (another business object) to the Order. Originally in my controller, I had a $scope.addBooking function that first created a new Booking, then took the order and did a $scope.order.bookings.push(newBooking). Instead, I moved this business logic (addBooking function) directly into my Order model, and in the template I could then do something like <button ng-click="order.addBooking()">Add Booking</button> without adding a single line of code into my controller.
A lot of the code I put in my controllers when I was first starting off with angular, I found could be stripped out and placed either in my models, directives, or services (mostly the first two in my case). The remainder of the code left in my controllers almost all fell into one of the above 3 roles I listed above. It was either initialization code (e.g. firing an AJAX request to fetch data of the relevant business objects), scope assignment of objects, or scope assignment of functions that dealt with application flow (e.g. $scope.save or $scope.cancel that might send you back to a different page).
Should controllers be model-centric or view-centric?
This is an interesting question, one that I haven't thought about before. When I hear view-centric, I think of a controller that deals primarily with the view and how things are displayed. I feel there shouldn't be any controllers that are purely view-centric, the reason being it seems a view-centric controller can probably be transformed into a directive. You mentioned view-centric controllers as being like a Dashboard controller, which sounds like something that could definitely be made into a generic directive. Your directives should encapsulate most of your view logic, while your controllers focus on simply exposing your models to the view for consumption (back to the role of the controller). This has me thinking that controllers should more often be model-centric.
I think really the only conclusion I can come to is if a controller starts becoming too view-centric (with many variables and functions that deal primarily with the view and UI behaviour) then that is a sign that parts of your controller can be pulled out into a directive, making your controller slimmer.
This is very subjective but here is my answer to your questions
should controllers be model-centric or view-centric?
It depends (as always), I always try to have small controllers for the different parts of the page.
Some parts of the page are very view-centric (typically the ones that are shared among the different views). I usually have a menuCtrl, a headerCtrl and footerCtrl. This ctrls are very coupled to those parts of the page so a make them view-centric.
The other parts of the view, the ones that are business related are much more coupled to the business rules and in extension to the model so I make those ctrls model-centric. On an account´s business app, I would probably have an accountCtrl, an ownerCtrl, and so on. By doing so I can reuse them on different views if needed (and are much easier to test)
what level of granularity should the controllers represent?
The smallest as possible. Try to have small controllers that prepare the model for different parts of the page. If you have a big controller it will be hard to test, maintain and you will probably be forced to duplicate code on different parts of your application.
advices and recomentations with controllers
Keep them small.
Avoid DOM manipulation inside of them (use directives instead).
Use the controllers just to prepare the model. whenever possible delegate all the logic of your app to services. If you do so, it won´t really matter that much if your controller is view-centric or model-centric.
As I said before this is a very subjective matter and I´m sure many people will disagree with me.
I hope this could help you.
Basic Idea
So I'm actually in the process of migrating a legacy code base over to a restful based web service architecture utilizing AngularJs
Controllers are responsible for managing the data that is consumed by the view aka the webpage. My personal preference is that there is a one to one relationship between the controller and the view that it is serving. So, based on the question, Angular controllers should be more view centric. I'm sure that there are plenty of people who will disagree with me though.
If you are worried about the extensibility of this pattern, you should place your business logic and data access within Angular Services as described here. This offers you a tremendous amount of reuse of business logic operations as well as unit testability.
TLDR;
The specifications for Angular are changing all the time and with each new version there will be a new standard. A more view centric architecture looks appropriate for this application.
For some more complete reading on the subject I recommend checking out:
3 Tips To Building Enterprise Grade Angular/Node Applications
Lessons Learned: A Year with a Large AngularJS Project

How do Gang of Four Design Patterns fit into the MVC paradigm?

I've mulled over Design Patterns for some time now and I am just starting to see how I might actually begin incorporating some of these more deliberately in my development work. However, I am still confused about their treatment of MVC in the beginning of the book and how it relates to the rest of the book.
Most of the frameworks I have worked with - Spring, Yii, ASP.NET, and even Objective-C Cocoa (UIKit) - cater to the MVC paradigm. I get MVC because to me it is a useful way of classifying objects and how they should message or interact with each other. Plus, these frameworks kind of force it upon you even if you are not setting out to think in the MVC way.
I also feel that I understand the premise of Design Patterns: they really don't like subclassing, they love abstract interfaces, and they strive for loose coupling. I can't say I fully understand all of the patterns yet or how they are useful, but I am getting a feel for it.
My question is this: what is the interplay between MVC and design patterns? What were they getting at in the first chapter of the book with the MVC application example? Are certain design patterns just not relevant in the MVC paradigm? I wonder, for example, how the Command pattern is supposed to fit into MVC. It seems incredibly useful, but do we create a CommandModel and CommandController to send to other controllers? Do we just create a Command object as prescribed in the book? Basically, I am wondering if the ideas of MVC and Design Patterns are wholly disjoint and I just don't understand, or if there are some patterns that do not fit into the mold.
My personnal opinion is that MVC is a simplified version of the Observer Pattern which is a simplified version of the Mediator Pattern.
MVC: One Model, One view, the Controler manages the communication between them.
Observer Pattern: One Model, Multiples views ( observers/subscribers ), and the publisher manages the communication
Mediator Pattern: Several different Models, Several views, and the mediator manages the communications between them.
The MVC in the GoF book is for the desktop, it uses the observer pattern to update views. The command example in the GoF book is for an editor.
There are other flavors of MVC where the use of other design patterns may not be obvious:
What is the difference between MVC and MVVM?
Presentation abstraction control
The GoF book says:
...
Taken at face value, this example reflects a design that decouples views from models. But the design is applicable to a more general problem: decoupling objects so that changes to one can affect any number of others without requiring the changed object to know details of the others. This more general design is described by the Observer (page 293) design pattern.
Another feature of MVC is that views can be nested. For example, a control panel of buttons might be implemented as a complex view containing nested button views. The user interface for an object inspector can consist of nested views that may be reused in a debugger. MVC supports nested views with the CompositeView class, a subclass of View. CompositeView objects act just like View objects; a composite view can be used wherever a view can be used, but it also contains and manages nested views.
Again, we could think of this as a design that lets us treat a composite view just like we treat one of its components. But the design is applicable to a more general problem, which occurs whenever we want to group objects and treat the group like an individual object. This more general design is described by the Composite (163) design pattern. It lets you create a class hierarchy in which some subclasses define primitive objects (e.g., Button) and other classes define composite objects (CompositeView) that assemble the primitives into more complex objects.
MVC also lets you change the way a view responds to user input without changing its visual presentation. You might want to change the way it responds to the keyboard, for example, or have it use a pop-up menu instead of command keys. MVC encapsulates the response mechanism in a Controller object. There is a class hierarchy of controllers, making it easy to create a new controller as a variation on an existing one.
A view uses an instance of a Controller subclass to implement a particular response strategy; to implement a different strategy, simply replace the instance with a different kind of controller. It's even possible to change a view's controller at run-time to let the view change the way it responds to user input. For example, a view can be disabled so that it doesn't accept input simply by giving it a controller that ignores input events.
The View-Controller relationship is an example of the Strategy (315) design pattern. A Strategy is an object that represents an algorithm. It's useful when you want to replace the algorithm either statically or dynamically, when you have a lot of variants of the algorithm, or when the algorithm has complex data structures that you want to encapsulate.
MVC uses other design patterns, such as Factory Method (107) to specify the default controller class for a view and Decorator (175) to add scrolling to a view. But the main relationships in MVC are given by the Observer, Composite, and Strategy design patterns.
...
MVC is a pattern. But it only covers a small aspect of a web application. Another common pattern that gets used with MVC is the Repository. These are more architectural patterns.... their scope has a bigger impact on the overall project.
the GOF patterns will introduce themselves in little ways all over the place. They can help build MVC infrastructure depending on design choices. eg, Strategy gets used a lot so you can plug in different ways of doing things like "authentication" etc.
You don't have to use the patterns as they are, they don't even have to be the exact same code structure. Its more the design principle / goal of the pattern that you employ in the design.
MVC is an architectural pattern. It perfectly fits with other design patterns like Command Pattern. But you do not apply patterns just because they exist and they are written in an authoritative book. You apply patterns when you have a programming/design problem and there is a way to solve that problem that was discovered by someone else and was written down. The way to solve a problem is a pattern. For example, you have an application that saves data to the database. Data to be saved is quite complex: some records must be inserted, some records updated and some deleted. The sequence of steps is important because the records to be inserted into one table depend on records to be inserted into another table. So, a database transaction must be used. One of possible ways to implement the transaction is to use Command Pattern. The way to do it is very well explained in Larman's "Applying UML and Patterns" book (chapter "Designing a Persistence Framework wth Patterns", section "Designing a Transaction with the Command Pattern" - scroll down to the page 556). PersistentObject is an abstract Model class there. All other Model classes extend it. In that example MVC is implemented in the UI, Application and Domain layers but Command is implemented in the Persistence layer. These patterns help to solve different problems and they are mutually supportive in that example.

MVC - View that needs multiple model

I have a problem at the conceptual level, I read a lot but I'm not out yet.
I would like to model a system that plans to place orders and allows you to choose the products according to the selected location.
In the analysis phase it is right that is the user interface to request data to the classes product, location and orders?
In the design phase, can view access to multiple models and display the data or is more correct if the orderView access only to the order model and this takes all the data from the database (using different DAO for location, order and product)?
Thanks in advance, Vincenzo
An approach to solve this is to use a ViewModel (http://geekswithblogs.net/michelotti/archive/2009/10/25/asp.net-mvc-view-model-patterns.aspx), basically a composite model that groups several other models together so that they can be serviced to a view.
So if you have a Product model and a Location model and an Order model, all logically distinct models that you want to combine together on a single view (e.g. Monthly Sales Summary), you could create a SalesSummaryViewModel that contains products, orders, and locations to be returned to that view.
You should consider Model View ViewModel, have ViewModel objects created for serving your view needs, composing your business object.
There are no absolutes
In the design phase "is it right..." is the wrong thing to say. Design is an exercise in trade offs. At the end of my treatise I hope you conclude that we're splitting hairs on a sound design concept that you should be adhering to.
Separating UI from Data from Managing their interaction is a good design goal
Whether you use MVP, MVC, MVVM is largely an academic exercise in this forum because we don't have the overall design details.
For arguments sake, let's just call the basic idea MVC. MVP is a variation of that and MVVM (ViewModel) is a specialization of our MVP.
MVVM / ViewModel is .NET Specific
Model-View-ViewModel pattern was created by microsoft architects to take advantage of the capabilities of WCF, XAML, and Silverlight (vis-a-vis ASP.NET and Windows Forms). In the final analysis it's a variation of our basic concept, a variation that leverages .NET technologies to be sure.
Exposing Model to View
.. or not is a judgement call on how much coupling you want between your model view controller components.
MVC gives your view a reference to your model. This is handy for data binding. If you use .NET Binding architecture then this pattern is what you may end up using.
MVP - only the Presenter (a Controller w/ more power, if you will) sees the data model. You can still use .NET Binding architecture, for example, but the presenter is the middle man hooking it all up. Why? Because you made that informed decision based on your overall design.
MVP means the Presenter intimately knows about the View and Model so it can wire them together and handle UI inputs. It therefore follows that there is a Presenter for each View as they are customized pairs, (most likely) not interchangeable.
Development Tools can Influence Design Architecture
For example if you are developing in .NET WCF you absolutely have no choice but to use MVVM; that's the way that framework works.
Likewise, Mac OS X development IDE forces you to use MVC. So does Ruby On Rails and .NET MVC web development
If you are using some kind of Object Relational Mapper (ORM) - and .NET LINQ is one - then your design may not have a Data Access Layer per se.
If you need an example, this is done in the music store http://mvcmusicstore.codeplex.com/releases/view/64379#DownloadId=228002.
The details are around p95 of the associated PDF.

Resources