I am wondering about how to approach inheritance with View Models in the MVVM pattern. In my application I have a Data Model that resembles the following:
class CustomObject
{
public string Title { get; set; }
}
class CustomItem : CustomObject
{
public string Description { get; set; }
}
class CustomProduct : CustomItem
{
public double Price { get; set; }
}
In my application I have a ViewModelBase class and then was going to have the following View Models:
- CustomObjectViewModel
- CustomItemViewModel
- CustomProductViewModel
A rough implementation of the CustomObjectViewModel would resemble the following:
class CustomObjectViewModel : ViewModelBase
{
private readonly CustomObject _customObject;
public CustomObjectViewModel( CustomObject customObject )
{
_customObject = customObject;
}
public string Title
{
// implementation excluded for brevity
}
}
It seems logical to me that my View Models would extend themselves in the same manner as my Model did (CustomItemViewModel extends CustomObjectViewModel and so on). However, I have noticed that as I go down the inheritance tree I'll be adding additional references to the same object. This seems rather excessive to me and was wondering how to approach this problem and if it were possible to make it much cleaner.
I'd be interested to see if there is a better answer for this, but when I have had the same problem I've always enclosed an explicit cast of the object as a private property like so:
It works, and it's the best I've come up with, but has never felt very clean to me.
Related to the comment above of Enrico. ViewModels should not be tightly coupled with views, it should be the other way around. Views should be loosely coupled to ViewModels. A ViewModel should not know about a view, this allows you to unit test a ViewModel easily.All interactions between Views with the ViewModel should be implemented via properties in the ViewModel(ICommand properties for actions and other properties for databinding).
The one thing that is true is that the ViewModel is tightly coupled with the Model, so the use of generics above allows alot of extensibility. It is the pattern that I would recommend.
By providing a ViewModel class that basically just exposes Properties it should allow you to plop that into any kind of presentation framework and leverage all the code you've used previously. In other words, if properly implemented you could drop your ViewModels assembly into a ASP.NET MVC app and tie the view to the properties and have no code change.
A good article on MVVM basics is : this one. I really think that MVVM is the best thing out there for UI development. Obviously we can't all use it because it requires building an app from the ground up using the MVVM approach, but when you're building a new app that is not an issue.
The one gripe I have with ICommand is that it is in the PresentationCore Assembly which is basically for WPF. If Microsoft wanted loose coupling it should be in another assembly altogether.
I think the issue here is that there should be one ViewModel for each View, and not one ViewModel for each model.
The reason for this is fairly obvious, as you can only set one object to be the DataContext, that object should be the ViewModel for that View.
Generally I would recommend you not to have inheritance between different ViewModel classes, but instead having them inherit directly from a common abstract base class.
This is to avoid introducing unnecessary complexity by polluting the ViewModel classes' interfaces with members that come from higher up in the hierarchy, but are not fully cohesive to the class's main purpose.
The coupling that comes with inheritance will also likely make it hard to change a ViewModel class without affecting any of its derived classes.
If your ViewModel classes always will reference a single Model object, you could use generics to encapsulate this rule into the base class: