Aspect powered WPF

In some of my first posts – as it turns out I can almost celebrate one year of blogging! – I wrote about a factory approach to solve the complexities and overhead of creating dependency properties (DPs) for a WPF control; and notify properties and commands for a viewmodel. Both are essential parts when using WPF and following the MVVM pattern. To summarize: the approach was basically to delegate the creation of these complex components to a factory contained within the class which uses annotations on fields (attributes) to clarify what should be created. To create DPs, this looked as follows:

public class HelloWorldControl : UserControl
{
    [Flags]
    public enum Properties
    {
        Hello,
        World
    {

    static readonly DependencyPropertyFactory<Properties> PropertyFactory
        = new DependencyPropertyFactory<Properties>( false );

    [DependencyProperty( Properties.Hello )]
    public string Hello
    {
        get { return (string)PropertyFactory.GetValue( this, Properties.Hello ); }
        set { PropertyFactory.SetValue( this, Properties.Hello, value ); }
    }

    [DependencyProperty( Properties.World )]
    public string World
    {
        get { return (string)PropertyFactory.GetValue( this, Properties.World); }
        set { PropertyFactory.SetValue( this, Properties.World, value ); }
    }
}

Nice and concise, but as mentioned in my conclusion there is still room for improvement:

  • Requirement of an enum.
  • Having to manually add the factory to the class.
  • Every property has almost the exact same implementation.

As it turns out, PostSharp is the perfect candidate to leverage the concept of Aspect Oriented Programming (AOP) to solve the last two problems, resulting in the following solution:

[WpfControl( typeof( Properties ) )]
public class HelloWorldControl : UserControl
{
    [Flags]
    public enum Properties
    {
        Hello,
        World
    {

    [DependencyProperty( Properties.Hello )]
    public string Hello { get; set; }

    [DependencyProperty( Properties.World )]
    public string World { get; set; }
}

Where does the magic happen?

Simply put, PostSharp does a post-compilation step, inserting the required code where needed. Which code needs to be inserted where is determined by applying aspects (exposed as attributes) to the relevant elements. The WpfControlAttribute in the example above applies an aspect to HelloWorldControl. PostSharp makes it relatively easy by allowing you to implement these aspects by using plain C# classes. It’s a mature framework with an extensive feature set as will become evident from the following more in-depth description.

A core used feature in the implementation is the ability to dynamically ‘provide’ aspects to the elements of your choice. The solution actually is composed of 2 aspects, WpfControlAspect and DependencyPropertyAspect, being applied to the user control and the dependency properties respectively.

  1. The WpfControlAttribute is actually an IAspectProvider, creating a WpfControlAspect and applying it to its target (HelloWorldControl in the example). This extra step is only required for generic aspects as a workaround since C# doesn’t support generic attributes. The generic type arguments are passed as an argument to the attribute, and reflection is used to instantiate the actual generic aspect.
  2. The WpfControlAspect introduces the factory into the user control, and in its turn provides a DependencyPropertyAspect to all members which have the DependencyPropertyAttribute applied to them.
  3. The aspects applied to the properties create the correct call to the DependencyPropertyFactory, where the actual logic is implemented.

This solution represents a personal guideline I prefer to follow when writing aspects.

Only resort to using aspects after applying encapsulation to its fullest extent.

It’s a gut feeling I have, and I can’t quite formulate thorough arguments for it yet. When I can, I’ll be sure to write about it! Perhaps the main advantage is you are less dependant on aspects, and let’s face it, minimizing dependencies is almost always a good thing. Basically I prefer to rely on .NET and its excellent debugging and testing tools as much as possible, and only use PostSharp where .NET fails to satisfy my DRY needs.

Why still use enums?

As explained before, they are a necessary replacement to identify the associated element which is created. They aren’t all that bad. As I will demonstrate in a next post, the enums can even be put to use in some interesting use cases. If you can’t wait, all source code and a particularly interesting unit test is already available for you to try out. If you haven’t installed PostSharp 2.1 RC2 or higher yet, you will need it! Actually I already discussed another use case in a previous post: binding from XAML to a command in the viewmodel by using a custom ‘CommandBinding‘ markup extension and passing the enum as a parameter.

It could be worthwhile to investigate an opt-in approach where only those elements which need to be identified from elsewhere need to be assigned an ID. At first sight it looks like the limitations for attribute arguments are a big deal breaker.

You’re breaking the conventions!

The only convention I am still breaking is that I’m not adding the DependencyProperty fields. As discussed before, I see no need why these are required. The sole stated problem is that tools could rely on this convention to access the properties. Opening a simple user control enhanced with aspect goodiness shows that both Blend and the Visual Studio designer work as expected. That’s good enough for me!

About these ads
  1. #1 by Gael Fraiteur on September 23, 2011 - 8:52 pm

    Hi Steven,

    Nice post! Yet, I still wonder why you’re using enums. Isn’t it enough to put the property name, which you know at build-time and at run-time? I also think it would be useful to see the source code of the aspect. It would be also useful to remind why you don’t introduce the static fields containing dependency attribute metadata (I suppose it’s in the first article).

    I think that would be a nice guest post on http://www.sharpcrafters.com/blog if you’re interested.

    -gael

    • #2 by Steven Jeuris on September 23, 2011 - 9:39 pm

      Hi Gael,

      In order to reduce errors and keep the code clean the strings would have to be stored as public const strings. Otherwise you have kind of an unrefactorable ‘magic numbers’ situation. Rather than having a bunch of those, I feel an enum is a better solution, unless an opt-in approach would work. Enums have some additional advantages, they are easy to identify and use through intellisense (e.g. from XAML); they can actually be recognized as a type, and be used for run time verification of a correct implementation. Furthermore, (untried and solely an assumption) I believe it would simplify solving possible conflict problems which could arise through inheritance, combining aspects, etc …

      As an example of run time verification check out some of the checks already implemented in: https://github.com/Whathecode/Framework-Class-Library-Extension/blob/master/Whathecode.System/Reflection/AbstractEnumSpecifiedFactory.cs

      I’d love to write up a guest post by composing the entire ‘story’ into one understandable post. It would require some effort though, as the subject is currently spread across 5 posts or more. Perhaps reaching a wider audience could be a first step towards a stable simplified wrapper around the Presentation Framework. I could send you a draft version somewhere next week.

  1. Attribute metabehavior « Whathecode

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: