Best implementation of INotifyPropertyChange ever
Back in May 2008, I found a way to use Linq expression to fire notification change, and just after that on September 2008, changing the first implementation to benefit extension methods, things looked a lot easier and more C# 3.0 style. But now to think of it, the best implementation of INotifyPropertyChange would be not to implement it at all! Is this possible?
If you’re a WPF or Silverlight programmer, you probably already know that to make data binding work on simple POCO objects, you need to implement INotifyPropertyChange interface on your POCO class. This is a trivial interface which has a public event. When property value changes, it is your job to notify interested parties about this change and WPF / SL engine is one of the interested parties and will update the UIElement that is bound to that property automatically. How to do that is actually easy too, but a lot of repetitive boiler-plate code should be written:
1 | public class Customer |
Yuck! Even using LINQ and Extension methods just changes the untyped property name to its typed equivalent but the amount of code written hardly changes.
Let’s see how we can just create an automatic property and make it notify the property change event, without doing all these stuff. In short, let us see how to make this red test turn green:
1 | [ ] |
Not possible at first look, eh? If you’re familiar with DynamicProxy tools, you can well see the perfect usage here. In short, using a dynamic proxy library, we could implement an interface on our type at runtime, so we could inject the INotifyPropertyChange behavior into our ViewModel here. This is a pretty powerful toy which allows you any kind of behavior into your objects with minimal effort.
Let’s create a ViewModelFactory for ourselves that just does that:
1 | public class ViewModelFactory |
We need to create an Interceptor for our behavior too. Interceptor as the name implies, will be called on our class at runtime and gives us a chance to run a piece of code before and / or after a call is made on our object.
1 | public class NotifyPropertyChangedInterceptor : IInterceptor |
As you can see, the IInvocation interface contains the method that is being executed so we can see if it is an event subscription, a property getter/setter or a method call and act respectively.
Now we only need to create our ViewModel classes via our factory so let’s refactor our test code to this and see the tests pass.
1 | var vm = ViewModelFactory.Create<CustomerViewModel>(); |
How does this fit to your application? It goes without saying that you can not create instances of your ViewModels and need to get new instances via this factory, but if you’re using a presentation framework like Caliburn, or using dependency injection containers like Windsor to resolve your VMs, you’ll feel right at home.
So, what’s the catch? There’s always a catch, you might ask? There’s no catch seriously. Well, now that you insist, there is just one point. To be able to do so, you need to make your properties virtual as the sample above. I don’t consider this a catch since making your public API virtual is considered a good thing for many reasons and you probably do that anyway.