First of all, a very, very "Happy New Year" to all my readers. If you are reading this post, then I’m assuming that you have a working experience of WPF using MVVM.
Don’t worry! I’m not going to re-write a huge post on what MVVM is and where to use it. This blog is very small which talks about one of the best practices any developer implementing MVVM should follow.
Well, let me provide you the context first. Last week, I was going through one of my colleague's code and noticed a few interesting things in his ViewModelBase class:
- It was holding a few Dependency properties
- It was inheriting DependencyObject
How does this sound to you? Good or … ?
Of course, that is not at all a good practice as ViewModelBase is the base class for all the ViewModels and is not supposed to contain such code. Well, this is not the only reason.
There are many other reasons which make this implementation a BIG NO.
First Reason
A DependencyObject was never meant to be a Source of a binding, but rather it is a Target, which means its existence should be in the UI layer. So, if we are inheriting DependencyObject in ViewModelBase class, then we are not adding dependencies on view related objects.
2nd Reason
DependencyObject overrides and then seal two methods, Equals and GetHashCode, with the reason to prevent derived classes to define value equality for a DependencyObject as such sort of value equality will never be accurate due to value changing capabilities of DependencyObject and its dependency properties. Hence inheriting DependencyObject class in ViewModelBase will never let you override Equals and GetHashCode methods. Official link .
3rd Reason
Serialization – If you want to Serialize anything in VM, it’s not going to happen because our Base class which is DependencyObject in our case is not Serializable. In other words, DependencyObject class is not marked as [Serializable]. So, the only solution left and that can be used as a workaround is to implement ISerializable in ViewModelBase class which is not a recommended solution here.
4th Reason
CLR properties still needs INotifyPropertyChange implementation.
5th Reason
Thread affinity – It says that an object created on one thread cannot be used by another. A DependencyObject has thread affinity which means it can only be used on the thread that created it.
Hence never ever derive ViewModelBase class from DependencyObject. Enjoy learning!!!