Latest Tweet:
  • Loading...

There has been lots of talk in the Silverlight community about what is the best way to implement the INotifyPropertyChanged interface. During Christmas I blogged about how you can use dynamic proxies to get INPC implemented automatically. Since then both Einar Ingebrigtsen and Justin Angel have blogged about an interesting approach to INPC using MSIL weaving. I really recommend checking out Justin’s post, as he covers some of the pros and cons of different INPC implementations, as well as purposing an elegant solution using post-build MSIL weaving.

One of the things Justin mentions as a drawback of the dynamic proxy approach is that you cannot simply new up your ViewModel directly and get change notification automatically. You have to explicitly create the ViewModel instance through a proxy creator. Einar also mentioned that he had a hard time finding a way to integrate the proxy creator with an IoC container.

When I write code I’m always careful about where I instantiate my objects, and lately all projects I’ve worked on have used some sort of IoC container. Having an IoC container gives you a single place in your code base to create- and register objects. If the dynamic proxy implementation of automatic INPC is going to be useful it has to be as simple requesting a ViewModel instance from the IoC container. In this blog post I’m going to show how you can combine automatic INPC using dynamic proxy with the Ninject IoC container.

If you have read my blog you may have noticed I got a soft spot for Ninject. I mean, who cannot love a framework whose name, graphic profile and code examples are all about Ninjas? When I first set out to integrate my automatic INPC interceptor with Ninject I wasn’t quite sure where to start. Ninject 1.0 had AOP concepts built in, but in 2.0 (which are under development) this has been moved out of the core and into a separate interception extension module. This is part of the new modular design of Ninject 2.0. Features you may not need all the time are moved out to separate extensions, leaving the core really small and simple (~90kb).

ninject-ninja

My first plan was to use the Ninject interception extension. The extension uses the LinFu framework for dynamic proxies, and I wasn’t sure how to get my Castle Dynamic Proxy based implementation to work directly. I later got contacted by Ian Davis, the owner of the interception-extension project. He asked if I needed some help getting automatic INPC working with Ninject. After some back-and-forth on Twitter Ian had an implementation of automatic INPC added to the Ninject.Extension.Interception project. The code is commited to the trunk, and is available on github if you want to check it out. Ian’s implementation is probably worth a blog post on its own.

A comment from Miguel Madero pointed me in the right direction to get my interceptor working with Ninject. Miguel had integrated it himself by implementing the interceptor as a Ninject Provider. Ninject lets you register types against providers which let you write code that creates the instance when the type is requested from the container. The interface is really simple, having one Create-method. In this method you have to create the instance being requested.

The implementation for the automatic INPC provider is fairly simply. It finds the largest constructor of the ViewModel being requested, creates instances of all constructor parameters, before calling the dynamic proxy creator I implemented in my previous two blog posts.

ProviderCode

In Ninject all configuration is done through code using an internal DSL. You configure the container by creating module classes specifying the bindings of the different types you want to be able to create. In this example I have a simple logging service (to demonstrate constructor injection combined with automatic INPC) as well as a simple ViewModel. The ViewModel is bound to the provider, which will call the proxy creator when the ViewModel is requested.

ConfigurationExample

This unit tests shows how to request an instance of the ViewModel from the container. When the Name-property is set the ViewModel will log the action to the fake logger which was injected into the ViewModel constructor.

ExampleUnitTestOfViewModelFromKernel

Having to register every single ViewModel against the provider is tedious and repetitive. Miguel Madero also suggested that you can override the GetBinding method of the Ninject StandardKernel and use convention over configuration. By overriding the GetBinding method we can check if the type being requested is a ViewModel, and if it is we can create a binding on the fly tying the ViewModel type against the automatic INPC provider.

The implementation of the AutoNotifyKernel is really simple. It checks if the name of the type being requested contains “ViewModel” and implements the IAutoNotifyPropertyChanged interface. If it does we create a binding for the type.

AutoNotifyKernel

Having a convention based approach in place we do not have to manually register every single ViewModel.

Some of this code might seem complicated, but I really wanted to cover the details of how to integrate it with Ninject, as similar approaches probably work for other containers. Once you got a framework for automatic INPC in place the usage becomes really simple. In the example application for automatic INPC the code needed to implement the ViewModel, configure the container and tie the ViewModel to the View looks something like this:

FullExample

It’s funny how such a simple interface can trigger so many different implementations. I hope you found my blog post on combining a dynamic proxy approach with an IoC container useful. It will be interesting to see which approach emerges as the most used, and which frameworks that will provide implementations of the different techniques.

Yesterday I published a post showing how we can use AOP and Castle Dynamic Proxy to get automatic change notification for ViewModels by intercepting property setters. One of the comments I got was from Krzysztof Koźmic who suggested that I should use ProxyGenerationHook to narrow down the scope of the proxy.

By implementing the IProxyGenerationHook we get to choose which methods to intercept. In my original implementation this logic was handled by the interceptor itself. The interceptor would check that the method being intercepted was indeed a property setter, that it was not of type ICommand, and that it was not marked for exclusion. By implementing a ProxyGenerationHook I could move all this code into a separate class, making my interceptor much cleaner. The ShouldInterceptMethod implementation of the ProxyGenerationHook now looks like this:

ProxyGenerationHookCode

I also got a good question from Anders Knutsen asking how to handle change notification for properties depending on another property. A typical scenario for a ViewModel might be to have a ZipCode-property with both setter and getter, and City and State properties with only getters. When you set the ZipCode you raise change notification for ZipCode, City and State. In the City- and State-getter you look up the values based on the ZipCode. This means that you must be able to raise multiple change notifications in a single setter.

I solved this by adding a new NotifyChangesFor-attribute that you can decorate properties with to trigger change notification for additional dependent properties.

NotifyChangeForAttributeCode

I have also updated the tests to document this behavior.

NotifiyChangesForTestCode

The sample code has been updated with the new ProxyGenerationHook and the new NotifyChangesFor-attribute.

As a WPF or Silverlight developer chances are you have implemented the INotifyPropertyChanged-interface more than once. The interface is simple enough, consisting of a single PropertyChanged-event. The data binding infrastructure in WPF and Silverlight will look for this interface and subscribe to the PropertyChanged-event. As a developer you have to write code in your property setters to raise the event whenever some property is changed. This is boring and repetitive code to write, that often contains magic strings (property names) and can really clutter your ViewModels. Finding an elegant implementation of the INotifyPropertyChanged-interface has become one of the holy-grails of WPF and Silverlight developers.

An idea I had some time back where to use AOP-techniques and dynamic proxies to get INotifyPropertyChanged implemented automatically. With the recent beta release of Castle Dynamic Proxy 2.2 with official support for Silverlight, combined with Christmas holiday, I figured this would be a good time to take a stab at this problem.

After doing some research I found a couple implementations of INPC using AOP. In August 2008 Gian Mari Ricci published two blog posts about automatic implementation of INPC. The first one he used Reflection.Emit and dynamic code generation, the second was a much simpler implementation using Castle Dynamic Proxy.

In June Ray Houston published an interesting post on how they had implemented auto wiring of INPC as part of the Fluent Silverlight framework. Fluent Silverlight is an open source framework by Ray Houston and Gabriel Schenker that provides a fluent interface for configuring data binding in a strongly typed manner using C#. Their implementation of automatic wiring of INPC is based on Castle Dynamic Proxy, and is really simple and elegant. Instead of trying to reinvent the wheel I decided to re-implement the automatic INPC parts from Fluent Silverlight, and walk you through the code in this blog post. I do not want to take credit for Ray and Gabriel’s work, and must emphasize that this should be considered a walkthrough of their implementation.

The first part of the implementation is a new IAutoNotifyPropertyChanged interface that extends the INotifyPropertyChanged interface with one new method. This interface will be implemented for any ViewModel where we want automatic change notification. The interface serves as both a marker interface for the interceptor, as well as providing a method that the interceptor can call to raise the PropertyChanged-event.

IAutoNotifyPropertyChanged Code Example (code download attached)

To create a new ViewModel we simply implement the interface, and make any property we want change notification for as virtual. The properties need to be virtual so that the generated proxy class can override the property setter method and call the interceptor. The implementation of the interface can off course be moved down to a base class, but I have included it in this sample to make it clear what is required by the ViewModel for automatic change notification.

PersonViewModelCode

With a ViewModel implementing the IAutoNotifyPropertyChanged-interface in place we can now write an interceptor that will add change notification for the properties on the ViewModel. Interceptors are a concept from AOP that enables us to intercept method calls and add new behavior dynamically. This is helpful as we can move cross-cutting concerns out of the business logic. Typical use cases for AOP often include authentication, logging, exception handling and other technical concerns. By having these concerns implemented outside our class we can keep our business logic nice and clean. In our case we are going to apply some of these techniques to keep the ViewModel free from change notification code cluttering the class.

The interceptor is defined as a generic class that intercepts classes implementing the IAutoNotifyPropertyChanged-interface. The interceptor implements IInterceptor-interface which defines a method that will be called for every method invocation, providing us a hook to add addition behavior to the method call. Our interceptor will start by letting the original method call (the property setter) run before checking if we should raise change notification. If the property being set isn’t marked for exclusion we call the OnPropertyChanged method on the IAutoNotifyPropertyChanged-interface, passing in the property name as the parameter.

InterceptorCode

The code to determine if we should raise change notification starts by checking if the method being invoked is in fact a property setter. This is done by checking the IsSpecialName-property on the MethodInfo object, as well as checking that the name of the method starts with “set_“. The second step is to check if the property is marked with a DoNotNotifyChanges-attribute. This is a marker attribute that can be applied on properties to prevent automatic change notification. The third step is to check if the property being set is of type ICommand. A common pattern when creating ViewModels is to expose operations as Commands hanging of the ViewModel as properties. You do not need change notification for commands, so they are ignored by the interceptor.

ShouldSurpressCode

Now that we have our change notification interceptor the only thing missing is a way to create the proxy object. To do this we create a new proxy creator. The proxy creator has a generic method that creates proxied instances of any class implementing the IAutoNotifyPropertyChanged-interface.

ProxyCreatorCode

This diagram illustrates how the View calls the property setter on the proxied ViewModel. The property setter gets intercepted, and the interceptor lets the original setter execute before raising the PropertyChanged-event.

AutoINPCDiagram

Now that we got the proxy creator it is really straight forward to create an instance of our ViewModel that will have automatic change-notification. I have included the tests documenting the behavior of the automatic change notification interceptor. The tests documents change notification for simple properties, as well as exclusion of commands and properties marked with the DoNotNotifyChanges-attribute.

AutoINPCTestsCode

Summary

Using dynamic proxies for automatic change notification is a good way to keep your ViewModels nice and tidy as well as not having to hand-write tedious, repetitive change notification code. In my next blog post I will explore how we can integrate the change-notification interceptor with the Ninject IoC-container. By integrating the interceptor with an IoC-container we can have any ViewModel retrieved from the container support automatic change notification.

For more information about Castle Dynamic Proxy I would recommend Krzysztof Koźmic excellent 15-part tutorial.

The example code for this blog post requires Silverlight 3, and includes the latest beta of Castle Dynamic Proxy 2.2. The code is experimental, and not intended for production use.

<September 2010>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789