DEV Community

Cover image for How to Get Rid of the INotifyPropertyChanged Boilerplate
Suresh Mohan for Syncfusion, Inc.

Posted on • Originally published at syncfusion.com on

How to Get Rid of the INotifyPropertyChanged Boilerplate

.NET is a great platform to write user interfaces. From Windows Forms to WPF to Xamarin, WinUI or Blazor, you can rely on the same platform and language on a broad range of devices.

As strong as .NET is as a UI platform, it is very useful to harness the functionality of third parties like Syncfusion. Syncfusion’s mission is to build beautiful and well-engineered UI controls that are ready to use in enterprise applications. With more than 1,600 components targeting over a dozen platforms, there’s no doubt Syncfusion excels at this task.

PostSharp’s tool automates the refreshing of projects’ UIs when business objects change and drastically reduces the boilerplate code required to do so. Together, these tools can save developers time and headaches when developing for .NET.

In this blog, I will explain how PostSharp improves the function of the INotifyPropertyChanged interface and show you an example using a UI created with some of Syncfusion’s compatible controls.

The problem with INotifyPropertyChanged Boilerplate

Unfortunately, integrating the UI with the business code in .NET is not an easy task. The most painful point is making the UI automatically refresh itself when your business objects get changed. For this to work, you need to implement the infamous INotifyPropertyChanged in every single class of your model and view-model layers. Typically, it means that instead of having each property on a single line, they will take six, like in the following example.

private string name;

public string Name
{
    get => name;
    set
    {
       name = value;
       RaisePropertyChanged("Name");
    }
}
Enter fullscreen mode Exit fullscreen mode

As if it were not enough to write six lines of code instead of one, the implementation of INotifyPropertyChanged is also a frequent source of bugs. It’s so easy to forget to raise a property change when you modify a field!

Enter PostSharp

Fortunately, there are tools that allow you to implement the INotifyPropertyChanged interface automatically, without any boilerplate code. One of these tools is PostSharp.

Instead of implementing the feature in every property, you just add a [NotifyPropertyChanged] custom attribute to your base class and you are done.

[NotifyPropertyChanged]
public class CustomerModel 
{
    public string Name { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

The previous example is completely covered by PostSharp Community, a free edition of PostSharp. It means that you can get rid of most of your boilerplate tomorrow if you want, and for free. The new source generators of C# 9.0 may also help reduce that boilerplate.

But there’s more than this case.

Unlike competing tools, PostSharp also supports composite properties like FullName. If you change FirstName or LastName, PostSharp will also say that FullName has changed.

[NotifyPropertyChanged]
public class CustomerModel 
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName => FirstName + " " + LastName;
}
Enter fullscreen mode Exit fullscreen mode

PostSharp also supports properties that are dependent on properties of children objects. This is very useful in the view-model layer, which typically exposes the model layer, augmented by a few read-only computed properties. Suppose, for instance, you want the font size to decrease when the customer has a long name. This would be especially annoying to implement in plain C# because you would need to react to changes in the child object. However, with PostSharp, this is a one-liner.

[NotifyPropertyChanged]
public class CustomerViewModel
{
    public double BaseFontSize { get; set; } = 12;

    public CustomerModel Customer { get; set; }

    public double FullNameFontSize
        => Customer.FullName.Length > 20 ? 
         this.BaseFontSize : 
         this.BaseFontSize * 1.2;
}
Enter fullscreen mode Exit fullscreen mode

How does it work?

Arthur C. Clarke, the co-author of “2001: A Space Odyssey,” famously said: “Any sufficiently advanced technology is indistinguishable from magic.” So, what’s the magic behind PostSharp?

Postsharp work flow
Source: PostSharp

PostSharp is a post-compiler. Once you add its NuGet packages to your projects, it inserts itself in the build process just after the C# compiler, loads the output of the compiler, analyzes it, adds the requested behaviors, and writes it back. PostSharp implements a technology named aspect-oriented programming which allows you, the developer, to teach the compiler how to automatically implement your most boring and repetitive tasks.

Just think about it. Can you teach someone to implement INotifyPropertyChanged? Certainly! How much inventiveness is needed for this task? In most cases, none! If something is boring and repetitive, it’s likely that an algorithm can do it better than a human being. That’s exactly why PostSharp was created.

When PostSharp sees the [NotifyPropertyChanged] attribute on the top of your class, it will first analyze the code of all your property getters to figure out to which fields, properties, or properties of children objects it is dependent. For instance, this algorithm will find that FullName is dependent on both FirstName and LastName, and that FullNameFontSize is dependent on FullName, Customer, and BaseFontSize.

Code showing dependency of each propertyThen, PostSharp will modify all methods (typically property setters, but not only) that modify the fields and will buffer property change notifications for the current thread.

Finally, PostSharp will modify public methods to detect when it is a good time to raise notifications. It is generally not a good idea to raise a notification immediately after a field has been changed because it may happen that the current method will modify another field just after, and you don’t want to raise notifications in the middle of a change. So, we will wait until the end of the execution of the top public methods. It’s a little detail that may seem to split hairs at first sight, but that will save you a lot of headaches.

Compatibility with Syncfusion product suites

As with any well-designed control suite, Syncfusion products support data binding through the INotifyPropertyChanged interface. PostSharp is able to enhance any project targeting .NET Framework, .NET Core, .NET 5, or .NET Standard. Therefore, you can use PostSharp Windows Forms and WPF, but also Xamarin and Blazor, as long as your view-model and model projects target .NET Standard. The following are the projects created with Syncfusion controls and PostSharp,

Summary

Today’s users expect the user interface to reflect the current state of the data without having to press F5—a feature you normally implement thanks to INotifyPropertyChanged. Instead of writing this code manually—which not only takes time but is also error-prone—you can use a tool like PostSharp. You will reduce approximately 80% of the INotifyPropertyChanged boilerplate and avoid subtle bugs.

PostSharp can also reduce the boilerplate that stems from WPF dependency properties, commands, logging, caching, multi-threading, transaction handling, and much more. There is a free PostSharp Community version that’s also available for commercial companies. To get started, watch the PostSharp MVVM introduction video, download the demo source code from GitHub, and start hacking.

Related blogs

Discussion (0)