Reputation: 54011
I'm interested in discovering the different ways that developers are using to abstract their views away from their domain models.
Currently I create a ViewModel for each model that I want to use in a view and I have a converter IConverter<TIn,TOut>
to do so.
What I'm noticing is that for types containing collections of other types, I have a ViewModel for each type in the heirarchy and converters that use other converters to build up the final ViewModel.
As an example:
Suppose I have this domain model structure that's built up with FluentNHibernate:
public class User
{
[...]
public virtual IEnumerable<QuestionSubscription> QuestionSubscriptions{get;set;}
}
public class QuestionSubscription
{
public virtual bool VerifiedSubscription{get;set;}
public virtual Question Question{get;set;}
}
Given the way I'm working this I'll then have 3 ViewModels to support this and since I use my custom converters there will be a chain of conversion from User down to Question: (shortened some names for brevity)
_userToUserViewModelConverter.Convert(userModel)
|
V
_qSubscriptionToViewModelConverter.Convert(userModel.QSubscriptions)
|
V
_questionToViewModelConverter.Convert(QSubscription.Question)
This is working great, I'm just wondering about other ways of managing this.
My first question is, do you think I'm taking the right approach by not letting my domain models touch my views?
Secondly, assuming "yes" to question 1, would you use the same approach of having the converters execute other converters or would you do each one at a time in the Controller?
Upvotes: 4
Views: 3238
Reputation: 1338
You should also take a look at ValueInjecter (yes, it's spelled that way). I have used both Automapper and ValueInjecter and find that in most situations, it's easier to use ValueInjecter as there is no setting up involved unlike Automapper. Automapper is better suited for more complex objects and objects with nested collections.
Upvotes: 0
Reputation: 591
I often have views that expose domain objects and I don't think there is anything wrong with that in most scenarios.
I find that flattening domain objects often makes my views more straight forward and understandable because I the object hierarchy is removed or at least decomplicated. It appears that your method is a way to flatten your object?
I would take a look at AutoMapper if you are not already familiar with it. It is what I usually use to flatten my domain objects down to views.
Upvotes: 0
Reputation: 8192
My first question is, do you think I'm taking the right approach by not letting my domain models touch my views?
The answer is: Yes, this is the right way of tackling software, as lots of paradigms like MVVM, MVC, MVP, MVPVM and all the others show, which all try to solve some problems arising from directly connecting model objects in a view.
Secondly, assuming "yes" to question 1, would you use the same approach of having the converters execute other converters or would you do each one at a time in the Controller?
Typically a ViewModel is an adapter between View and Model.
Therefore, there is >typically< not a ViewModel for every class in your model, but a ViewModel that represents an abstract part that will be shown in a view.
This can be for example a whole Formular, a List, and especially an item in a list, which often consists of 1..n objects of your model. But: the most interesting point of the ViewModel is, that it gets all those data in a shape that can be easily bound (binded?) by the view. This way the view has some easy munchable way of accessing the data it needs. and if designed right, it only has to do small updates if the model changes.
There are some really good sources on what the model is and how to architect an application that is aware of change, i.e. maintainable and testable, i.e. it is easy to assert that your software does what is expected.
I suggest reading: WPF Application Framework (WAF) / MVVM in layered architecture
Upvotes: 0
Reputation: 5843
Look at the nested mappings in automapper: Nested mappings
This will save you tons of time and if you are using ORM on a project, mappings will become a piece of cake in no time :)
Upvotes: 4