Hello Stackoverflowers! :)
Today I have a special question on Silverlight (4 RC) MVVM and inheritance concepts and looking for a best practice solution... I think that i understand the basic idea and concepts behind MVVM. My Model doesn't know anything about the ViewModel as the ViewModel itself doesn't know about the View. The ViewModel knows the Model and the Views know the ViewModels.
Imagine the following basic (example) scenario (I'm trying to keep anything short and simple):
My Model contains a ProductBase class with a few basic properties, a SimpleProduct : ProductBase adding a few more Properties and ExtendedProduct : ProductBase adding another properties. According to this Model I have several ViewModels, most essential SimpleProductViewModel : ViewModelBase and ExtendedProductViewModel : ViewModelBase. Last but not least, according Views SimpleProductView and ExtendedProductView. In future, I might add many product types (and matching Views + VMs).
1. How do i know which ViewModel to create when receiving a Model collection?
After calling my data provider method, it will finally end up having a List<ProductBase>. It containts, for example, one SimpleProduct and two ExtendedProducts. How can I transform the results to an ObservableCollection<ViewModelBase> having the proper ViewModel types (one SimpleProductViewModel and two ExtendedProductViewModels) in it?
I might check for Model type and construct the ViewModel accordingly, i.e.
foreach(ProductBase currentProductBase in resultList)
if (currentProductBase is SimpleProduct)
viewModels.Add(
new SimpleProductViewModel((SimpleProduct)currentProductBase));
else if (currentProductBase is ExtendedProduct)
viewModels.Add(
new ExtendedProductViewModels((ExtendedProduct)currentProductBase));
...
}
...but I consider this very bad practice as this code doesn't follow the object oriented design. The other way round, providing abstract Factory methods would reduce the code to:
foreach(ProductBase currentProductBase in resultList)
viewModels.Add(currentProductBase.CreateViewModel())
and would be perfectly extensible but since the Model doesn't know the ViewModels, that's not possible. I might bring interfaces into game here, but I haven't seen such approach proven yet.
2. How do i know which View to display when selecting a ViewModel?
This is pretty the same problem, but on a higher level. Ended up finally having the desired ObservableCollection<ViewModelBase> collection would require the main view to choose a matching View for the ViewModel.
In WPF, there is a DataTemplate concept which can supply a View upon a defined DataType. Unfortunately, this doesn't work in Silverlight and the only replacement I've found was the ResourceSelector of the SLExtensions toolkit which is buggy and not satisfying.
Beside that, all problems from Question 1 apply as well.
Do you have some hints or even a solution for the problems I describe, which you hopefully can understand from my explanation?
Thank you in advance!
Thomas