-1

I'm writing a small wpf desktop application. My BaseViewModel looks like this:

public abstract class BaseViewModel : INotifyPropertyChanged, IComparable<BaseViewModel>
{
    public abstract string GetDisplayText();
    public abstract string GetImageName();

    // INotifyPropertyChanged
}

I was looking for a best paxis for mvvm. The most say, that there are multiple ViewModels for one Model and I agree to it.

Because I want that all ViewModels of the same type handle the basics in the same way, i thougth they should derived from each other.

public abstract class BaseCustomerVm : BaseViewModel
{
    public abstract string Name { get; set; }
    public abstract int Number { get; set; }
    public abstract bool IsPerson { get; set; }

    public override string GetDisplayText()
    {
        return Name;
    }

    public override string GetImageName()
    {
        if (IsPerson)
            return "Person";
        else
            return "Company";
    }
}

public class Customer1Vm : BaseCustomerVm
{
    public override string Name { get; set; }
    public override int Number { get; set; }
    public override bool IsPerson { get; set; }
}

To implement this, I have the following options:

Version 1:

public class Customer2Vm : BaseCustomerVm
{
    public override string Name { get; set; }
    public override int Number { get; set; }
    public override bool IsPerson { get; set; }
    // Further Properties
}

Version 2:

public class Customer2Vm : Customer1Vm
{
    // Further Properties
}

In my search, I read ViewModels shouldn't derive from each other. This was also answerd in this post. My questions are:

  1. Why should I not derive in this way?
  2. What would be the correct way to handle sutch basics with no inheritance?
RCP161
  • 199
  • 1
  • 13
  • 9
    *"In my search, I read ViewModels shouldn't derive from each other"* -- In mine, I read that the moon landing was fake. I'd apply the usual rules for deciding whether to write a subclass or not. – 15ee8f99-57ff-4f92-890c-b56153 May 29 '18 at 14:55
  • 2
    There is nothing that says that a view model shouldn't derive from another view model. There is the composite reuse principle but that's another thing: https://en.wikipedia.org/wiki/Composition_over_inheritance – mm8 May 29 '18 at 14:57
  • 1
    By the way, `GetDisplayText` and `GetImageName` should be abstract properties `DisplayText` and `ImageName`, not methods. You'll most likely want to be able to bind them, and even if not, they're the kind of thing that is customarily a property. – 15ee8f99-57ff-4f92-890c-b56153 May 29 '18 at 14:58
  • 1
    To expand on my first comment: That answer you found is saying that, if you apply usual common sense rules, you'll rarely find a case where there's any good reason for your viewmodel hierarchy to be deeper than `AbstractViewModelBase` -> `FooViewModel`. I haven't found it to be as rare as he suggests, and I've been doing WPF at work for several years now. Use your own judgment case by case. – 15ee8f99-57ff-4f92-890c-b56153 May 29 '18 at 15:11

2 Answers2

0

As far as if Customer2Vm should derive from Customer1Vm; I think you want the classic inheritance question:

Does Customer2Vm have a "is-a" relationship with Customer1Vm?

Only you know; but based on the names I would doubt it. Sounds to me like they should both be deriving from BaseCustomerVm.

As far as whether or not you should be using inheritance at all; I would say that it largely seems OK here. If you wanted to avoid it (and strictly prefer composition) I would suggest making your VMs implement an ICustomerVm interface to get the properties; and then the consumer would use services to get the display text and image name. I would probably stick with what you have (assuming its more or less exactly what you've shown).

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
0

Inheritance shouldn't be an issue until you reach the point where you need to inherit from more than one (base) view model, i.e. if you have several different base view models that provide their own common base functionality.

Since you can't inherit from more than one class in C#, you then need to break out the common functionality into reusable components that you can inject into your view models.

But the only way you will be able to directly bind to some common properties that are defined in a class is to use inheritance and there is nothing wrong with inheriting from a chain of different base view model classes. In fact, this is a pretty common approach in my experience. Most of the types used in the view (Control, FrameworkElement, etc.) also do this.

mm8
  • 163,881
  • 10
  • 57
  • 88