Geeks With Blogs
// ThomasWeller C#/.NET software development, software integrity, life as a freelancer, and all the rest

Lately I played around a bit with Aspect Oriented Programming, especially with PostSharp. I wanted to see how I could use it to reduce the amount of infrastructural code that clutters a common class like this:

public class Person : INotifyPropertyChanged

{

    private string firstName;

    private string lastName;

    private int age;

 

    public string LastName

    {

        get { return this.lastName; }

        set

        {

            // check the argument value

            if (value == null)

            {

                throw new ArgumentNullException("value");

            }

            if (value == "")

            {

                throw new ArgumentException("Last Name must not be empty.", "value");

            }

            if (value.Length > 50)

            {

                throw new ArgumentException("Last Name must not be longer than 50 characters.",

                                            "value");

            }

 

            // do nothing when trying to set the same value twice

            if (value == this.lastName)

            {

                return;

            }           

 

            // set the value

            this.lastName = value;

 

            // fire PropertyChanged events

            this.OnPropertyChanged("LastName");

            this.OnPropertyChanged("FullName");

        }

    }

 

    public string FirstName

    {

        get { return this.firstName; }

        set

        {

            // check the argument value

            if (value != null)

            {

                if (value.Length > 30)

                {

                    throw new ArgumentException("First Name must not be longer than 30 characters.",

                                                "value");

                }

            }

 

            // do nothing when trying to set the same value twice

            if (value == this.firstName)

            {

                return;

            }

 

            // set the value

            this.firstName = value;

 

            // fire PropertyChanged events

            this.OnPropertyChanged("FirstName");

            this.OnPropertyChanged("FullName");

        }

    }

 

    public string FullName

    {

        get

        {

            return (this.firstName + " " + this.lastName).Trim();

        }

    }

 

    public int Age

    {

        get { return this.age; }

        set

        {

            if (value < 18 || value > 65)

            {

                throw new ArgumentOutOfRangeException("value", "Age must be between 18 and 65.");

            }

 

            this.age = value;

        }

    }

 

    #region INotifyPropertyChanged implementation

 

    public event PropertyChangedEventHandler PropertyChanged;

 

    private void OnPropertyChanged(string propertyName)

    {

        if (PropertyChanged != null)

        {

            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

        }

    }

 

    #endregion // INotifyPropertyChanged implementation

 

} // class Person

Most of the code of this class is value-checking and a bit of INotifyPropertyChanged-logic, like you frequently have it with business objects and some sort of Model-View-Presenter/Controller-style UI coupling or WPF. But no matter how important such code is in terms of correct program behavior, it is repetitive and boring - certainly not the kind of stuff that made me become a developer. Code like this is mostly written in the 'classic' copy-paste-modify coding style, with all the problems that this may bring...

Now look at that:

[Validate, NotifyPropertyChanged(OnPropertyChanged = "OnPropertyChanged")]

public class PersonWithAspects : INotifyPropertyChanged

{

    [NotNullOrEmpty, MaximumLength(50)]

    [PropertyChangedDependency("FullName")]

    public string LastName { get; set; }

 

    [PropertyChangedDependency("FullName")]

    [MaximumLength(30)]

    public string FirstName { get; set; }

 

    [InRange(18, 65)]

    [NoPropertyChangedEvent]

    public int Age { get; set; }

 

    public string FullName

    {

        get

        {

            return (this.FirstName + " " + this.LastName).Trim();

        }

    }

 

    #region INotifyPropertyChanged implementation

 

    public event PropertyChangedEventHandler PropertyChanged;

 

    private void OnPropertyChanged(string propertyName)

    {

        if (PropertyChanged != null)

        {

            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

        }

    }

 

    #endregion // INotifyPropertyChanged implementation

 

} // class PersonWithAspects

This version of the Person class is absolutely identical to the first one in terms of behavior (except that it throws a different exception type), but it has almost no hand-written code, only some declarative attributes. This reduced the number of code lines for the properties in this simple example from 36 to 11 - or by about 70%! Wow...

I did it with the ValidationAspects aspect library, that sits on top of the PostSharp aspect weaver and allows for placing Design by Contract - like attributes on properties (and also on method arguments). Additionally, I took the INotifyPropertyChanged sample from the PostSharp 1.5 download and modified it slightly to include the NoPropertyChangedEvent and PropertyChangedDependency attributes. It was not much work, and the result is quite impressive, I think.

Besides the pure technical aspects (much better readability and expressiveness, dramatically reduced error-proneness etc.), code like this gives me the warm feeling of having done a good job. In fact, deleting code (while preserving functionality) is one of my favorite activities in writing software. I know that this might sound a bit strange from someone who calls himself a software developer - but if you think about it for a minute, it perfectly makes sense...

 

kickit
shoutit
delicious facebook digg reddit linkedin stumbleupon technorati mrwong yahoo google-48x48 twitter email favorites
Posted on Tuesday, September 15, 2009 6:41 AM Readability , Architecture and Design , General programming/C# , Aspect-oriented programming | Back to top


Comments on this post: AOP can save you tons of repetitive code

# re: AOP can save you tons of repetitive code
Requesting Gravatar...
Great work with this.

One suggestion, unless other code of yours is explicitly subscribing to the events, shouldn't it be possible to move the actual implementation of INotifyPropertyChanged to being weaved in by PostSharp also? This wouldn't effect runtime subscription to the event by databinding infrastructure. Now that would really by the icing to this...
Left by Sean Blakemore on Sep 18, 2009 1:49 AM

# re: AOP can save you tons of repetitive code
Requesting Gravatar...
Hi Sean,

thanks for the kind words.

Doing what you suggest would of course be the most elegant solution in terms of aspect implementation, and it would reduce the number of code lines even more, leaving only the bare minimum.
The reason why I decided to not do it that way in the end is - as you suppose - that I think the INotifyPropertyChanged interface should be visible for calling code (to do things like mocking, event subscription, casting...) and for readers. Totally 'hiding' the interface behind an aspect IMHO would make the code slightly less flexible and expressive.

- Thomas
Left by Thomas Weller on Sep 18, 2009 5:39 AM

# re: ccan save you tons of repetitive code
Requesting Gravatar...
very detailed and helpful information for my site about AOP
Left by essay on Sep 23, 2009 3:05 PM

# re: AOP can save you tons of repetitive code
Requesting Gravatar...
This is pretty cool-- I love the idea aspect-oriented stuff for things like INotifyPropertyChanged.

Do you think that "[PropertyChangedDependency("FullName")]" could be taken a step further? It seems like some kind of static analysis could see that two other properties participate in the definition of "FullName", and could apply the equivalent PropertyChangedDependency automatically. I'm dreaming of either a trick to get ReSharper to do this for me, or a class-level aspect that could somehow accomplish this with a similar concision to your example, which is awesome.
Left by Luke Winikates on Jan 05, 2012 9:35 PM

# re: AOP can save you tons of repetitive code
Requesting Gravatar...
Thanks for your hardworking on it, i really enjoy it.
Left by Cheap Jeremy Scott Wings on Mar 04, 2013 7:06 AM

Your comment:
 (will show your gravatar)


Copyright © Thomas Weller | Powered by: GeeksWithBlogs.net