Showing posts with label aop. Show all posts
Showing posts with label aop. Show all posts

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