Which layer should construct a View Model?
Asked Answered
F

5

15

I'm using the S#arp Architecture. I can't remember where I read it, but I understand that view models should be stored at the service layer, and your views should submit the view model to the service for processing.

My question then is this: Which layer should construct the view model? Should it be at the service layer, with the controller requesting it? Or should the controller construct the view model itself? There is also a question about updating the view model since, if it contains collections, and the model state is invalid, you will also need to repopuplate any lists.

Any suggestions?

Fuqua answered 27/4, 2010 at 9:34 Comment(0)
C
10

I create view models inside controllers. Controllers take domain entities (retrieved from database by model binders), possibly inside other view models, contact repositories for additional data, create new view model, and pass it to appropriate view (or redirect). So controllers responsibility is to prepare view/viewmodel according to input domain data (and handle errors of course).

You can look here for alternative to creating view models in controller. This technique moves view model creation outside actions, so that not only controller actions accept pure domain objects, but they also return pure domain objects. I wouldn't say it's appropriate in all cases, but it's very interesting to learn.

The above technique, related to AutoMapper, also raised questions similar to "should I pass viewmodels to service layer". No you don't. If you need to pass complex object to service or domain layer, you define this object in the appropriate service/domain layer and use it to pass data to those layers. This object then can be easily mapped to/from view models (for example, using AutoMapper). But your lower layers (service/domain) should not be coupled to upper layers (view/controllers). Not in this case, not in others. Never low level layers should depend on something defined above them.

Cracker answered 27/4, 2010 at 11:55 Comment(3)
Thats pretty much what I am doing now, but I must be doing something wrong as I seem to have a lot of conditional logic when minding the view model back to the domain. Maybe I need to break my view up into smaller chunks.Fuqua
I currently have an edit view which addapts based on the status of the entity. Would I be better off creating multiple views for the different states?Fuqua
Without seeing your edit view and models, this is hard to answer.Cracker
C
13

As per the traditional approach or theory wise, ViewModel should be part of User Interface(UI) layer. At least the name says so.

But when you get down to implementing it yourself with Entity Framework, MVC, Repository etc, then you realise something else.

Someone has to map Entity Models with ViewModels(DTO mentioned in the end). Should this be done in A) the UI layer (by the Controller), or in B) the Service layer?

I go with Option B. Option A is a no-no because of the simple fact that several entity models combine together to form a ViewModel. We may not pass unnecessary data to UI layer, whereas in option B, the service can play with data and pass only the required/minimum to the UI layer after mapping (to the ViewModel).

But, let us assume we go with Option A, we put ViewModel in the UI layer(and entity model in Service layer).

If the Service layer needs to map to the ViewModel, then the Service layer need to access ViewModel in UI layer. Which library/project? The Viewmodel should be in a separate project in the UI layer, and this project needs to be referenced by Service Layer. If the ViewModel is not in a separate project(.dll), then there is circular reference, so no go. It looks awkward to have Service layer accessing UI layer but still we could cope with it.

But what if there is another UI app using this service? What if there is a mobile app? How different can the ViewModel be? Should the Service access the same view model project? or will all UI projects compete?

After these considerations my answer would be to put the Viewmodel project in Service Layer. Every UI layer has to access the Service layer anyways! And there could be a lot of similar ViewModels that they all could use (hence mapping becomes easier for service layer). Mappings are done through linq these days, which is another plus.

Lastly there is this discussion about DTO. And also about data annotation in ViewModels. ViewModels with data annotations cannot reside in service layer. So then DTO will be an exact copy of ViewModel with a one on one mapping between the two(say with AutoMapper). Again DTO still has the logic needed for the UI(or multiple applications) and resides in Service Layer. And the UI layer ViewModel is just to copy the data from DTO, with some 'behaviour'(eg: attribute) added to it.

[Now this discussion is about to take an interesting turn read on...:I]

And don't think data-annotation attributes are just for UI. If you limit the validation using System.ComponentModel.DataAnnotations.dll then the same ViewModel can also be used for front-end & backend validation(thus removing UI-residing-ViewModel-copy-of-DTO). Moreover attributes can also be used in entity models. Eg: using .tt, Entity Framework data models can be autogenerated with validation attributes to do some DB validations like max-length before sending to the back end. Another advantage is that if backend validation changes in DB then .tt (reads DB specifics and create the attribute for entity class) will automatically pick that up. This can force UI validation unit tests to fail as well, which is a big plus(so we can correct it and inform all UIs/consumers instead of accidentally forgetting and failing). Yes, the discussion is moving towards a good framework design. As you can see it is all related: tier-wise validation, unit test strategy, caching strategy, etc.

Although not directly related to the question. 'ViewModel Façade' (viewmodel inside another viewmodel) & 'command' mentioned in this must watch channel 9 link is also worth exploring(@11:48 it starts)

Corder answered 7/7, 2012 at 7:25 Comment(3)
I feel like basic seperation of concerns and "Do one thing, and do it well" trumps "We may not pass unnecessary data to UI layer". I don't want my service layer to have to have to maintain every different variation of UI that will need this logic.Discountenance
@whiteleyJ then let the UI query the data it needs through REST API. So service do not need to have the logic. Either way, we cannot pass a single unit of data that is unnecessary. With REST Api, the onus of testing relies on the client. If we do not take into consideration automated testing and ownership then any approach works. Where ever the logic is, there we need automated testing(unit/integration tests)Corder
and in the answer even-though the obvious conclusion is "We may not pass unnecessary data to UI layer" , we are still proceeding with it to see if it fails for other reasons.Corder
C
10

I create view models inside controllers. Controllers take domain entities (retrieved from database by model binders), possibly inside other view models, contact repositories for additional data, create new view model, and pass it to appropriate view (or redirect). So controllers responsibility is to prepare view/viewmodel according to input domain data (and handle errors of course).

You can look here for alternative to creating view models in controller. This technique moves view model creation outside actions, so that not only controller actions accept pure domain objects, but they also return pure domain objects. I wouldn't say it's appropriate in all cases, but it's very interesting to learn.

The above technique, related to AutoMapper, also raised questions similar to "should I pass viewmodels to service layer". No you don't. If you need to pass complex object to service or domain layer, you define this object in the appropriate service/domain layer and use it to pass data to those layers. This object then can be easily mapped to/from view models (for example, using AutoMapper). But your lower layers (service/domain) should not be coupled to upper layers (view/controllers). Not in this case, not in others. Never low level layers should depend on something defined above them.

Cracker answered 27/4, 2010 at 11:55 Comment(3)
Thats pretty much what I am doing now, but I must be doing something wrong as I seem to have a lot of conditional logic when minding the view model back to the domain. Maybe I need to break my view up into smaller chunks.Fuqua
I currently have an edit view which addapts based on the status of the entity. Would I be better off creating multiple views for the different states?Fuqua
Without seeing your edit view and models, this is hard to answer.Cracker
T
3

These articles might be interesting to you:

DDD : Command Query Separation as an Architectural Concept

Better Application Services and CQS using S#arp Architecture

There is a sample application associated with the 2nd article that has the view and form models in a services layer, instead of the controller.

Thurlow answered 7/5, 2010 at 16:27 Comment(2)
This is the correct answer. I do, however, usually start with the ViewModel in the controller and migrate it to the service layer as the controller evolves.Crosswalk
Links are down at the moent, maybe sharp-architecture.readthedocs.io/en/latest/… will help?Baiel
A
1

I implemented a Wpf application but got a problem when implementing the ViewModel in a separate layer. Why? When I finished the application they wanted also a Web version of it. Then I had to implement a different ViewModel also in that layer for Web. That did not feel right. The Solution? Implement the ViewModels in Web and Wpf application. Let the repository return a Entity. Then in the Controller or Code-Behind in Wpf fill the ViewModel with the content of the Entity. The Entity is a Data Transformation Object (DTO). It transfers from an Entity in a ViewModel. The Blip Sample application from Pluralsignt is wrong about that.

But the most BIGGEST reason to implement the ViewModels in Web or Wpf application itself is that the are depending on that typ of View. With layers you want to be indepented as much as possible. With a ViewModel in lets say a Data layer that layer becomes depending on the UI. The Views of Web and Wpf are different. A Web has annotations and Wpf has NotifyProperty statements, so keep it where it belongs.

Actionable answered 24/2, 2020 at 12:4 Comment(0)
M
0

also look at Who Can Help Me -- it's fantastic. this framework is based on S#arp Architecture. it has lots of guidance for View/Form/Edit viewModels amongst other things.

Marinemarinelli answered 19/5, 2010 at 18:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.