There has been a big debate at the bank about how best to implement INotifyPropertyChanged on Model classes that need to support change notifications.
None of the approaches seem entirely satisfactory, and here is a quick rundown of the main contenders:
- Default approach – hard-code string representations of the property name that’s changing –> this is the easiest approach, and the one that’s included in most documentation, but it can quickly introduce subtle binding errors in WPF if you forget to re-write the strings when you refactor your model classes.
- Derive Model classes from DependencyObject and use the WPF dependency system for change notifications –> This is an effective solution, but breaks down if you want to do good unit testing. Also architecturally its not good, as your model classes now depend on systems designed to support WPF controls.
- Wrap your model classes in their own ViewModel that implements the interface –> this is a sound solution, but requires the coding of additional decorator classes, and can lead to a lot of code-bloat.
- Use Lambda Expressions –> this is refactor-proof, but is a poor performer as deciphering the lambda expressions in order to get at the property name uses reflection. Even though lambda expressions are lazy-compiled, there’s still a significant performance hit and the coding style seems counter-intuitive, which may confuse junior developers.
- Get the name of the current method inside the property setter, and then strip out the ‘set_’ part of the method name –> this is a really ugly solution, and may not work if you obfuscate the code.
- Look at the method call stack inside a helper class –> really ugly code and fragile if refactored.
- Derive your model classes from ContextBoundObject so they can be automatically remoted, and then inject AOP code into the message sink-chain –> are you serious !!!
None of the approaches are great, and every one requires the original Model class to be modified in order to support the approach.
So I thought – how about a generic class that derives from DynamicObject, and implements INotifyPropertyChanged.
With such a class you’d achieve the following:
- Automatic property changed notifications without changing a line of code on your model classes
- The solution is completely refactor-proof
- It performs reasonably well
- The additional memory consumption and strain on the GC is negligible.
- It a ‘’one size fits all’ solution
So, here’s my implementation:
As you can see, the only minor initial performance hit is when reflecting the classes type for the first time, which is then cached in a static dictionary.
And here is it being used:
As you can see if you run this code, clicking on the update button changes the value of the name property via the dynamic proxy, which publishes the change notification.