Open sandboxFocusImprove this doc

DOM008: OnPropertyChanged Method Is Missing

Severity Error
Reported by PostSharp.Patterns.Model
Message Class "<Class>" implements INotifyPropertyChanged but does not define a method with the signature void OnPropertyChanged(string propertyName), through which the [NotifyPropertyChanged] aspect raises the PropertyChanged event. The method can also be named NotifyOfPropertyChange or RaisePropertyChanged.

Cause

When a class already implements INotifyPropertyChanged, by itself or through a base class, the NotifyPropertyChangedAttribute aspect does not introduce the interface. It raises the existing PropertyChanged event through a method of the class instead, because only the class that declares an event can raise it.

The aspect looks for an instance method that returns void and takes a single string parameter, named OnPropertyChanged, NotifyOfPropertyChange or RaisePropertyChanged, in the class or in its base classes, with any visibility except private in a base class. When it finds none, it reports DOM008 on the class.

In the following example, Customer raises its PropertyChanged event in a method named NotifyChanged, which the aspect does not recognize.

using System;
using System.ComponentModel;
using PostSharp.Patterns.Model;

namespace Errors.DOM008_Error;

// The class has no OnPropertyChanged(string) method, through which the aspect would raise the event.
[NotifyPropertyChanged]
public class Customer : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;

    public string? Name { get; set; }

    protected void NotifyChanged( string propertyName )
    {
        this.PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( propertyName ) );
    }
}

public static class Program
{
    public static void Main()
    {
        Customer customer = new Customer();
        customer.PropertyChanged += ( _, e ) => Console.WriteLine( $"{e.PropertyName} changed." );
        customer.Name = "Alice";
    }
}
error DOM008: DOM008_Error.cs(9,14): Class "Errors.DOM008_Error.Customer" implements INotifyPropertyChanged but does not define a method with the signature void OnPropertyChanged(string propertyName), through which the [NotifyPropertyChanged] aspect raises the PropertyChanged event. The method can also be named NotifyOfPropertyChange or RaisePropertyChanged.

Resolution

  • Name the method that raises the event OnPropertyChanged, and give it the signature void OnPropertyChanged(string propertyName). The names NotifyOfPropertyChange and RaisePropertyChanged, used by some MVVM frameworks, also work.
  • Otherwise, remove the implementation of INotifyPropertyChanged from the class, and let the aspect implement the interface.

In the following example, the method is renamed OnPropertyChanged, and the aspect raises the event when Name changes.

using System;
using System.ComponentModel;
using PostSharp.Patterns.Model;

namespace Errors.DOM008_Fixed;

[NotifyPropertyChanged]
public class Customer : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;

    public string? Name { get; set; }

    // The aspect raises the PropertyChanged event through this method.
    protected void OnPropertyChanged( string propertyName )
    {
        this.PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( propertyName ) );
    }
}

public static class Program
{
    public static void Main()
    {
        Customer customer = new Customer();
        customer.PropertyChanged += ( _, e ) => Console.WriteLine( $"{e.PropertyName} changed." );
        customer.Name = "Alice";
    }
}
Name changed.

See Also

Reference

NotifyPropertyChangedAttribute
INotifyPropertyChanged

Other Resources

Implementing INotifyPropertyChanged
Understanding the NotifyPropertyChanged Aspect