Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to scope C# view models

I have a view that shows list of people. For said view I created a PersonListViewModel

class PersonListViewModel { 
    public IEnumerable<Person> People {get;set;}
    public int TotalPersonCount {get;set;}
    public int PeoplePerPage {get;set;}
    public string OrganizationName {get;set;}
}

My question is about Person class. Where should Person class be defined? And what should I call it?

This problem is an instance of more general problem of mapping types between bounded contexts or layers. I understand that I can use AutoMapper and such to do some of this work, but AutoMapper only alleviates the problem but does not solve it.

Here some options that I have considered along with pros and cons:

Put both PersonListViewModel and Person classes in the same namespace, e.g. Whatever.Organization.ViewModels.

Pro: Person class name shows what it is - a person, and context this class is bound to specified by namespace. Con: In a presenter where I build this Person instance will (most likely) collide with Person class from business domain space, so I will have to prefix one of them. Con: will have to add a namespace to contain view models (not necessarily a problem, since you might, and I do, already have a namespace for view models).

Nest Person inside PersonListViewModel class. Pro: Can have multiple Person classes for different view models. Pro: Person is naturally scoped to a view model it belongs to. Con: Can not reuse Person between views and view models. Inb4: I do believe that ViewModels shall not be reused, I do believe it is to reuse a non-viewmodel object definition in presentation layer when appropriate. This approach does not allow for such reuse, and in 5% of cases where it is necessary - I don't want to create a different pattern.

Postfix every presentation layer object with *ViewModel Pro: solves the problem of reuse and name collisions. Con: makes no sense since Person is only a view model when it contains data for a view, which might or might not be the case -- for example if person instance is given to a [sub]view - then, technically, it will be a view model, but if it is used as a property on PersonListViewModel then Person is not a view model (no more than int of TotalPersonCount is a view model, which it is not).

So far I don't have a solution that would make me happy. But solution #1 seems to be most correct (theoretically speaking), still I am hopeful a better solution will be suggested.

like image 906
THX-1138 Avatar asked Nov 12 '22 08:11

THX-1138


1 Answers

I would go with option 3. Why would a Person ever be passed to a view if it doesn't contain data for the view? ViewModels in general should only contain the data required by the view. There's nothing wrong with creating a PersonViewModel to pass data for a Person across that is to be consumed by the view. If the view doesn't require it, don't pass it across.

The fact that you are creating a PersonListViewModel implies that you are doing something presentational with a list of people in your view. It makes perfect sense to therefore create a PersonViewModel for holding the display data that you will be displaying in your view for each person held within your list.

like image 115
levelnis Avatar answered Nov 14 '22 21:11

levelnis