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 colleagues’ code and noticed few interesting things in his ViewModelBase class:
- It was holding few Dependency properties
- It was inheriting DependencyObject
How it sounds 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 are making this implementation a BIG NO.
1st 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 a 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 gonna 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 can be used as a workaround is to implement ISerializable in ViewModelBase class which is not 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 means it can only be used on the thread that created it.
Hence never ever derive ViewModelBase class from DependencyObject. Enjoy learning!!!