Fluent Silverlight – Auto Wiring INotifyPropertyChanged

In Gabriel’s introductory post for Fluent Silverlight, he showed that the code typically associated with implementing INotifyPropertyChanged can be reduced to a simple auto property. This can really improve the clarity of a large class as well as save some typing. I’m going to show you how to get it setup.

INotifyPropertyChanged

First lets talk a little about normal INotifyPropertyChanged. This is an interface that is typically implemented on a ViewModel that you wish to participate in two way data binding between itself and some sort of DependencyProperty which typically lives on a control. The interface declaration looks like:

public interface INotifyPropertyChanged
{
event PropertyChangedEventHandler PropertyChanged;
}
 
The PropertyChanged event on this interface is used to notify the control of any updates of properties that happen in your ViewModel so that the control can be refreshed with any updated data. Without the use of this interface, your updates will end up only being one way. Which means that the ViewModel will be updated with any changes from the control, but the control will not be updated with the changes from the ViewModel. A typical implementation may look like:
public class MyViewModel : INotifyPropertyChanged
{
private string name;
public string Name
{
get { return name; }
set
{
if (value == name) return;
name = value;
OnPropertyChanged("Name");
}
}

private int age;
public int Age
{
get { return age; }
set
{
if (value == age) return;
age = value;
OnPropertyChanged("Age");
}
}

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
As you can see, it makes for a lot of noise. Also make note of the “Name” and “Age” strings which are not very refactor friendly.

IAutoNotifyPropertyChanged

We got to thinking that if we could intercept the changes to the properties (AOP), then we could automatically throw the PropertyChanged event. One way to do this is to use Castle.DynamicProxy (the Silverlight edition). DynamicProxy allows us to create a runtime generated subclass of our ViewModel. The generated subclass allows interception of any virtual member where we can chose to do what we please. To get it all started, we needed an interface that would allow us to trigger the event:

public interface IAutoNotifyPropertyChanged : INotifyPropertyChanged
{
void OnPropertyChanged(string propertyName);
}

Next we updated our ViewModel to implement the new IAutoNotifyPropertyChanged interface and removed all the extras:

public class MyViewModel : IAutoNotifyPropertyChanged
{
public virtual string Name { get; set; }
public virtual int Age { get; set; }

public event PropertyChangedEventHandler PropertyChanged;

public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

As you can see, there is a lot less noise here and we don’t have the magic strings for the property names laying around. Also note that we made the properties virtual so that they can be intercepted. To actually make the auto wiring work, we have to create an instance of the ViewModel class (actually it’s a generated subclass) using our AutoNotifyPropertyChangedProxyCreator. I’m not sure if we’ll stick with that name, but it will do for now. Take a look at the following little test:

[TestFixture]
public class when_creating_viewmodel_with_creator
{
private MyViewModel model;
private string lastPropChanged;

[SetUp]
public void SetUp()
{
model = new AutoNotifyPropertyChangedProxyCreator().Create<MyViewModel>();

model.PropertyChanged += (s, e) => lastPropChanged = e.PropertyName;

lastPropChanged = null;
}

[Test]
public void should_send_property_changed_for_given_property()
{
model.Name = "test";

Assert.That(lastPropChanged, Is.EqualTo("Name"));
Assert.That(model.Name, Is.EqualTo("test"));
}
}

Because the proxy is a subclass, we can treat it as it’s original type MyViewModel. As the Name property changes, it fires the PropertyChanged event which is wired to update the lastPropChanged field.

Summary

INotifyPropertyChanged is a handy interface for doing two way data binding but it causes a lot of extra noise in your classes. In Fluent Silverlight, we have introduced the IAutoNotifyPropertyChanged interface which is used in conjunction with AutoNotifyPropertyChangedProxyCreator which uses Dynamic Proxy to intercept the calls and auto throw the PropertyChanged event. This allowed us to reduce the noise and completely remove the magic strings typically associated with standard INotifyPropertyChanged.

In a future post I’ll demonstrate how you can do other things with this such as ignore certain properties, tap into the interception to execute methods and have an IoC container handle the proxy creation.

Related Articles:

    Post Footer automatically generated by Add Post Footer Plugin for wordpress.

    About Ray Houston

    Ray is a software development leader and architect with 20 years hands-on experience. He enjoys finding elegant solutions to complex problems and delivering real value to customers. Ray is a speaker and contributor to community events.
    This entry was posted in Dynamic Proxy, Fluent Silverlight, INotifyPropertyChanged, MVVM. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

    4 Responses to Fluent Silverlight – Auto Wiring INotifyPropertyChanged

    1. Sorin says:

      You must notice “Outlining” options in your IDE. I don’t see a gain with this auto-wiring.
      Anyway another method is to use an aspect oriented programming tool and insert, after compile, the notifications of property changed (you must flag the class or methods with a custom attribute – personally I’ll go with method )

    2. Christian Granwehr says:

      Thank you Ray, I just come home from drinking a beer with Gabriel. He told me about your solution. Great job. Hope to hear more from you. Greetings from switzerland. (Hi Gabriel: you’re right I should read more blogs)

    3. Hi,

      That is very bad that we need to implement OnPropertyChangeEvent each time. However I see the source of this dirty code. Silverlight doesn’t support GetValue reflection method for private fields. =)

      What Unit Test Framework are u using in you example? As I see it it not MS Test Framework. Please give me an url to that project.

      Thanks,
      Alexey Zakharov.

    4. Jay Tuley says:

      I’ve also tried to reduce ViewModel boilerplate it’s been released as ImpromptuInterface.MVVM — Apache 2.0 Licensed. It actually works pretty sweetly for WPF, however I generally do not do silverlight development and was surprised to find out that it doesn’t work as ideally for silverlight, although I did find a work around using indexer bindings that makes it usable…I think. Anyway, it’s a different solution to a similar problem, I thought you might be interested, and i’d certainly be interested in feedback from a silverlight developer looking to make code readable.

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    *

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>