Monday, September 07, 2009

Implementing INotifyPropertyChanged by using Unity Interception

This example uses Unity interception to be able to bind objects to a UI by just applying a [Notify] attribute to a property, this done by intercepting the call and propagating it to a INotifyPropertyChanged implementation.
From MSDN:
The INotifyPropertyChanged interface is used to notify clients, typically binding clients, that a property value has changed.

Step 1 create an abstract class that encapsulates all the functionality we need.
See below for a class diagram:


Step 2 create the handler:
NotifyPropertyChangedHandler which inherits from ICallHandler
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) {

IMethodReturn result = getNext()(input, getNext);

if (!input.MethodBase.Name.StartsWith("set_")) return result;
//Remov the set_ to get the property's name
var propertyName = input.MethodBase.Name.Remove(0, 4);
//invoke the modified property
//maybe we should check if the target is indeed o BindableOjectBase ;)
BindableObjectBase target = (BindableObjectBase)input.Target;
((IBindableObject)target).Modified(propertyName);
return result;
}

Step 3: Create the attribute
Create a NotifyPropertyChangedAttribute class which inherits from HandlerAttribute
create a default constructor:
public NotifyPropertyChangedAttribute() {
_CallHandler = new NotifyPropertyChangedHandler();
}

override the folowing method
public override ICallHandler CreateHandler(IUnityContainer container) {
return _CallHandler;
}
Step 4: Setting up the UnityContainer:
UnityContainer_Container = new UnityContainer();
//Registring interception extension
_Container.AddNewExtension();
_Container.RegisterInstance(instance);
_Container.Configure().SetDefaultInterceptorFor(new TransparentProxyInterceptor());
var object container.Resolve();

the last step took a little time to get it working the way I wanted since DI usually works by injecting interface implementations but this was not what I wanted to do. Since interfaces define behaviour and properties have nothing to do with behaviour but with state.

I will post the full source code later