Push generic ViewModel function to base class?

I am using MVVM with Prism and Silverlight. I have several different views on one model. As I write more views, their ViewModels seem to duplicate a lot of the common code associated with processing this model. Instead of repeating the same common code in all virtual machines, I have a desire to return it back to the model (which is likely to affect the problems too much). Or maybe in some kind of common base class ViewModel? Or maybe my virtual machines need a 2nd level of a “shared virtual machine” between them and the model? This single shared instance, a second-tier VM will consolidate behavior and state shared by several regular virtual machines.

Any comments on these issues and possible approaches?


Thanks for the comments guys. I probably should have told you more about the specific "general" VM code.

I can see how the future code is in the VM base class, but the specific "general" code that I am looking at seems to belong to INotifyPropertyChanged implemented by the model itself. It is partly based on this other thread .

I don’t think this violates the SoC, because the model is inherently dynamic. Some of its properties are valid only at certain times. This dynamic nature of the model is not only important for the user interface, the corresponding unit test will also take care of this. Therefore, this model seems to need INotifyPropertyChanged.

Any comments on this?

+1
source share
4 answers

If the common code can be common to all ViewModels, then you should put it in the base ViewModel type.

If shared code is only shared using ViewModels that interact with a particular model, then a “shared” ViewModel is the way to go.

+1
source

I used inheritance for ViewModels in the New York Times Silverlight Kit to reduce replicated code. Take a look at CommunityRecentComments and its parent CommunityBase class for an example.

0
source

Most of the "base ViewModel classes" in various MVVM environments typically contain INotifyPropertyChanged support and usually some support for sending back to the user interface stream.

In addition, I think that if you have several ViewModels that share the functionality that should be in the base class, the more I use this template, the more I find myself using a fairly shallow ViewModels hierarchy, the basic ViewModel for code is common to all models of views and, as a rule, one more base class, which is used for general functionality in this area of ​​the user interface. Usually common commands or where the user interface combines elements.

ViewModelBase -> ProductsViewModelBase -> NewProductViewModel

0
source

In SoapBox Core , which is fully MVVM, I defined the IViewModel interface and the AbstractViewModel base class, which, as Nigel said, just implements INotifyPropertyChanged. (Note that SoapBox Core is WPF, not Silverlight, but in this case it is not very important. I did a similar job to Silverlight too.)

Then I defined more interfaces (e.g. IMenuItem) that inherit from IViewModel and more abstract classes that provide a basic implementation of these interfaces.

Now this takes into account the whole ViewModel tree, but, as you said, there is also a model tree. I spent almost a year working with MVVM now and here, my great insight: do not write a model. If you are building an application from scratch, just put everything in a ViewModel, otherwise you end up duplicating a ton of code.

The only cases when I was worried that I had a model when I used a third-party library that did not implement INotifyPropertyChanged, and therefore it is not easy to link. I believe that automatically generated code for entity frameworks may also occur here, but I noticed that some entity structures now provide you with the ability to implement INotifyPropertyChanged in the entities themselves.

Seriously, we need to rename it to the ViewModel template and make it with it. :)

0
source

All Articles