3

I'm developing a WPF with MVVM pattern, .NET Framework 4.6.1. and C#.

My question is not about WPF, it's about using composition instead of inheritance with these two classes:

public class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChangedEvent(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

And:

public class MainViewModel : ObservableObject
{
    private string statusPrinter;

    public string StatusPrinter
    {
        get { return statusPrinter; }
        set
        {
            statusPrinter = value;
            RaisePropertyChangedEvent("StatusPrinter");
        }
    }
}

MainViewModel inheritance from ObservableObject and I don't want to use inheritance.

I can do this:

public class MainViewModel
{
    private string statusPrinter;
    private ObservableObject observable;

    public string StatusPrinter
    {
        get { return statusPrinter; }
        set
        {
            statusPrinter = value;
            observable.RaisePropertyChangedEvent("StatusPrinter");
        }
    }

    public MainViewModel()
    {
        observable = new ObservableObject();
    }
}

But it seems to be a problem with public event PropertyChangedEventHandler PropertyChanged; in ObservableObject when I use composition. The problem is when XAML link.

Can I use composition here or do I have to use inheritance?

VansFannel
  • 45,055
  • 107
  • 359
  • 626
  • 2
    It's a very strange requirement. Why don't you want inheritance here? – Dennis May 04 '16 at 08:06
  • @Dennis I read the book `Microsoft .NET: Architecting Applications for the Enterprise, Second Edition` and it talks about avoid inheritance. – VansFannel May 04 '16 at 08:16
  • 1
    For the sake of your future sanity, replace those hard-coded strings with `nameof` statements! You surely must be alright using C# 6 if you're targetting .NET 4.6.1 – TheInnerLight May 04 '16 at 08:29

1 Answers1

8

You cannot use composition here, at least not in a way you presented. When something wants to subscribe to notifications for property changes for your MainViewModel object - it will first check if MainViewModel implements INotifyPropertyChanged. It does not in your case - so it cannot notify anyone about property changes.

If you don't like to inherit from ObservableObject - don't. Just implement INotifyPropertyChanged in MainViewModel, there is nothing wrong with it.

Evk
  • 98,527
  • 8
  • 141
  • 191
  • Thanks. I thought about your solution and if I use it I will need to implement `INotifyPropertyChanged` on every `ViewModel` class. I read the book `Microsoft .NET: Architecting Applications for the Enterprise, Second Edition` and it talks about avoid inheritance and use composition. But I think I could use composition when it is possible, but this is not the case. – VansFannel May 04 '16 at 08:16
  • 2
    INotifyPropertyChanged implementation could be a good example of what is called Mixin in some programming languages (https://en.wikipedia.org/wiki/Mixin). It's small piece of behavior which can be reused without inheritance. But C# does not support Mixins so you have to implement it over and over again or use inheritance indeed, even if it feels wrong for you. Composition however is not fit here anyway. As for composition - google for "composition over inheritance" and you will find many links with reasonable examples of that (even in wikipedia). – Evk May 04 '16 at 08:19
  • Implementing `INotifyPropertyChanged` is actually a great example of how to implement _Composition_, so in effect `INotifyPropertyChanged` is _how_ you implement _composition_ in this case. – Chris Schaller Jul 06 '22 at 08:16