Archive for the ‘AOP’ Category

Introducing PostSharp to your team

Wednesday, September 16th, 2009

PostSharp is AOP (Aspect-Oriented-Programming) framework (http://www.postsharp.org/).
It transparently inserts itself in the build process and post-processes the compiled assembly.

To enable PostSharp in your project you need to download and run the PostSharp installer, and add appropriate references in your project.

However if your project is in SVN, and you are not the only one compiling it (other developers, CI machine) most likely you don’t want to run PostSharp installer on all the machines.

There is a way to introduce PostSharp transparently to your project.

  1. Put all the PostSharp files in the \Lib\PostSharp folder of your project and add this folder to SVN.
  2. Modify the .csproj file:
    After the last ItemGroup following xml must be inserted:

      <PropertyGroup>
        <DontImportPostSharp>True</DontImportPostSharp>
      </PropertyGroup>
    
  3. Modify the .csproj file:
    After the

    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    

    following xml must be inserted:

    <Import Project="..\Lib\PostSharp\PostSharp.targets" />
    

    The whole change should be similar to this sample:

    </ItemGroup>
      <PropertyGroup>
        <DontImportPostSharp>True</DontImportPostSharp>
      </PropertyGroup>
      <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
      <Import Project="..\Lib\PostSharp\PostSharp-1.5.targets" />
    </Project>
    

INotifyPropertyChanged with PostSharp 1.5

Tuesday, September 15th, 2009

If you are doing WPF development, most likely you are tired of writing property implementations that raise PropertyChanged event manually:

public class MainWindowViewModel : ViewModel
{
    private string _message;

    public string Message
    {
        get
        {
            return _message;
        }
        set
        {
            _message = value;
            OnPropertyChanged("Message");
        }
    }

    // ...
}

PostSharp is a great tool to make such things simplier.

Let’s look at the specific ViewModel class that has a Message property that is bound to some UI element using XAML:

public class MainWindowViewModel : ViewModel
{
    [RaisePropertyChanged]
    public string Message { get; set; }

    // ...
}

Notice the RaisePropertyChanged attribute, which we’ll implement later.

Here’s our base ViewModel class that provides actual implementation of the INotifyPropertyChanged interface:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged
        = delegate { };

    public void OnPropertyChanged(string propertyName)
    {
        PropertyChanged(this,new PropertyChangedEventArgs(propertyName));
    }
};

Finally the PostSharp attribute:

[Serializable]  // required by PostSharp
public class RaisePropertyChangedAttribute : OnMethodBoundaryAspect
{
    private string _propertyName;

    /// <summary>
    /// Executed at runtime, after the method.
    /// </summary>
    public override void OnExit(MethodExecutionEventArgs eventArgs)
    {
        ViewModel viewModel = (ViewModel)eventArgs.Instance;
        viewModel.OnPropertyChanged(_propertyName);
    }

    public override bool CompileTimeValidate(MethodBase method)
    {
        if (IsPropertySetter(method))
        {
            _propertyName = GetPropertyName(method);
            return true;
        }
        return false;
    }

    private static string GetPropertyName(MethodBase method)
    {
        return method.Name.Replace"set_", "");
    }

    private static bool IsPropertySetter(MethodBase method)
    {
        return method.Name.StartsWith("set_");
    }
};

Note that we are validating if the method is in fact a property only during compilation time using CompileTimeValidate method.

During compile time appropriate invocations of OnPropertyChanged method will be injected after every set operation applied to the Message property.