NotifyPropertyWeaver: The new killer for INotifyPropertyChanged

I found this project several days ago.

This project uses Mono.Cecil to “weave” your assemblies after compilation.

From the google code website you can see this example:

//Original
public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public string GivenNames { get; set; }
    public string FamilyName { get; set; }

    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }

}

//Weaved
public class Person : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;

    private string givenNames;
    public string GivenNames
    {
        get { return givenNames; }
        set
        {
            if (value != givenNames)
            {
                givenNames = value;
                OnPropertyChanged("GivenNames");
                OnPropertyChanged("FullName");
            }
        }
    }

    private string familyName;
    public string FamilyName
    {
        get { return familyName; }
        set 
        {
            if (value != familyName)
            {
                familyName = value;
                OnPropertyChanged("FamilyName");
                OnPropertyChanged("FullName");
            }
        }
    }

    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }

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

Some interesting points:

  • It works on almost all versions of SL and WPF (read more).
  • It works if you already have a base class with any invoker method name (read more).
  • It has a very sophisticated algorithm to detect when it has to inject the invocation (read more).
  • It show very useful information on the output console when you build the project.
  • It doesn't need any reference to any assembly.
  • You can tell the weaver to try to inject on any members of any type. (read more)
  • You can tell explicitly in which properties you want the invocation (with an attribute and a reference that is removed after weaving).
  • You can mix implicit and explicit mode.

I’ve been writing about automatically implementing INotifyPropertyChanged with DynamicProxy and there are other solutions like PostSharp, but I think this is the best option so far.

Cons of the DynamicProxy version

There are two main concerns with the DynamicProxy version:

  • WPF and Silverlight databinding infrastructure use a lot of reflection, with dynamicproxy sometimes things simply wont work. Marco Amendola wrote about some workarounds  (link link).
  • DynamicProxy versions that I saw doesn’t handle readonly scenarios like FullName or does but in a very inefficient and complex way.

Cons of the PostSharp version

Like the DynamicProxy version, PostSharp versions that I saw, doesn’t handle readonly scenarios like FullName. I started a thread in the “Sharing Ideas” forum a on July of 2010, because I thought this was an important (and possible) feature to the framework, but the answer was that it wasn’t possible (read the full thread here surprisingly enough I gave they the same example that is in the NotifyPropertyWeaver main page). Gael Fraiteur said about an alternative approach, like having a code as follows:

public class Person
{
  [NotifyPropertyChanged(Dependants = "FullName")]
  public string FirstName{get;set;}

  [NotifyPropertyChanged(Dependants = "FullName")]
  public string LastName{get;set;}

  public string FullName
  {
    get{ return FirstName + " " + LastName; }
  }
}

I’ve never used it, and I’ve never used PostSharp for INPC, because I don’t see any advantage compared the standard way in such cases.

Because PostSharp is a general purpose AOP framework and it can do a lot of things more than the NotifyPropertyWeaver, the weaved code may look unfamiliar and very complex. I don’t think it is inefficient or slow code, and it is not an issue for me, but I hear other people to say that.

Finally

Don’t get me wrong, PostSharp and DynamicProxy are both great frameworks and they are useful for lot of other things. I really like PostSharp as an AOP framework, using Mono.Cecil to modify your assemblies is not something than mortals like me can do on daily work, but I can implement a PostSharp aspect with few lines of code.

However my advice for INotifyPropertyChanged is to use this framework.

Kudos for Simon Cropp for the amazing work and for be willing to hear opinions about his project. I started to tweet about his project, and he immediately added me to twitter and gtalk. This says a lot about him and his commitment as an OSS project lead.


blog comments powered by Disqus
  • Categories

  • Archives