Transparent change tracking for properties

While working to develop a framework for communicating with SharePoint 2007 from Silverlight I found the need to have some way of tracking changes to property values without having to implement the same code in all properties.

Luckily, my colleague Einar Ingebrigtsen wrote a blog post about automagically implementing INotifyPropertyChanged which was perfect for this.
I’ll skip the details in this post as Einar’s post does this very well, instead I’ll focus on my usage of this technique.

The idea is that anyone using this framework can implement their own strong typed versions of an SPListItem so you can have code like this:

public virtual string Title { get; set; }

instead of having to specifically call various methods like this:

private string title;
public virtual string Title {
    get {
        return title;
    }
    set {
        SetPropertyValueDirty("Title");  //this marks the property as changed and stores its old value
        title = value;
        OnPropertyChanged("Title");  //implementation of INotifyPropertyChanged
    }
}

Being that these things are now handled automagically, you can focus on doing what you want in your code. The proxy class that is generated to do this will also respect your code, so while it will call these methods in the example above it will also run your code.

It also gives you the possibility of undoing changes to properties or resetting the entire object by reading from the storage you’ve implemented to hold the value changes (for example a dictionary) like so:

public object GetOldValueForProperty(string propertyName) {
    if (dirtyDictionary.ContainsKey(propertyName))
        return dirtyDictionary[propertyName];
    else
        throw new ArgumentException("Property does not have an old value");
}

Or just reset the property back to its original value:

public void ResetPropertyValue(string propertyName) {
    PropertyInfo pInfo = this.GetType().GetProperty(propertyName);
    if (pInfo != null) {
        pInfo.SetValue(this, GetOldValueForProperty(propertyName), null);
        CleanProperty(propertyName);
    }
}

As you see, the example above uses reflection to set the value. While reflection is an expensive operation, it is the only way I can use in the framework to set the value because I only have the name of the property in the case of classes implemented by a third party. If anyone has a better solution, I’m all ears 🙂

Another reason for needing this, is so I can known if a value needs to be written back to SharePoint or skipped.

As always, if anyone have any questions or suggestions for improvements – please let me know 🙂