In my ASP.NET app, I have a Person
and a PersonViewModel
.
My Person
was generated by LinqToSql
. It has the properties that will be persisted in the database.
My PersonViewModel
has everything Person
has, plus a couple "select lists", which will be used to populate combo boxes, as well as a FormattedPhoneNumber
(which is basically a PhoneNumber
with dashes and parenthases added).
I originally just made Person
a property on my PersonViewModel
, but I was thinking that would mean the page would have to "know" whether something was a Person
property or PersonViewModel
property. For example, for name, the view would request pvm.Person.Name
, but for the phone number, the view would request pvm.FormattedPhoneNumber
. If I use inheritance, then everything the view needs would always be a direct property of the view model, hence pvm.Name
.
This sounds great, but, there is no real "is-a" relationship here (i.e., I don't really think it makes sense to say "a PersonViewModel
is a Person
), and it seems to fly in the face of "preferring composition over inheritance". Still, I'm having difficulty thinking of a scenario where I'd need the ability to swap out a Person
for something else. If I do this, it would no longer be a PersonViewModel
.
What say you? Inherit from Person
or keep Person
as a property (or something else entirely)? Why?
Update
Thanks for all the answers.
It looks like the inheritance idea has been almost universally rejected, and for some sound reasons:
Decoupling the classes allows the
ViewModel
to contain only the properties from the domain model that are needed, plus any additional properties. With inheritance, you naturally expose all public properties from the domain model, which may not be a good idea.The
ViewModel
doesn't automatically need to change just because the domain model changed.As Jay mentioned, decoupling the
ViewModel
facilitates view-specific validation.As Kieth mentioned, using a Mapper (such as AutoMapper) can eliminate a lot of the tedious work in mapping common properties between classes.