视图模型继承和重复的模型引用 [英] viewmodel inheritance and duplicate model references

查看:124
本文介绍了视图模型继承和重复的模型引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是:如何管理的ViewModels的继承链

My question is: How to manage an inheritance chain of viewmodels?

我的情况:

我M有一个标准的 ViewModelBase 只实现了INotifyPropertyChanged接口。

I'm having a standard ViewModelBase which only implements the INotifyPropertyChanged interface.

此外,我有一个 BusinessObjectViewModel 有一个GUID,一个 PersonBaseViewModel 它具有人的核心数据,一个< STRONG> CustomerViewModel 客户相关的东西和一个 EmployeeViewModel 与员工相关的东西。

Furthermore I have a BusinessObjectViewModel which has a Guid, a PersonBaseViewModel which has the persons core data, a CustomerViewModel with customer related stuff and a EmployeeViewModel with employee related stuff.

所有的ViewModels肯定封装了modelobject(客户,员工,PersonBase)。

All viewmodels certainly encapsulate a modelobject (Customer, Employee, PersonBase).


  • BusinessObjectViewModel从ViewModelBase继承

  • PersonBaseViewModel从BusinessObjectViewModel继承

  • CustomerViewModel从PersonBaseViewModel继承

  • EmployeeViewModel从PersonBaseViewModel继承

  • BusinessObjectViewModel inherits from ViewModelBase
  • PersonBaseViewModel inherits from BusinessObjectViewModel
  • CustomerViewModel inherits from PersonBaseViewModel
  • EmployeeViewModel inherits from PersonBaseViewModel

该机型标配通过构造成视图模型。

The model comes via constructor into the viewmodel.

如果我使用构造函数链(每视图模型使得调用基类的构造)每个视图模型有它的模型,从模型返回封装的值。

If I use a constructor chain (every viewmodel makes a call to the base constructor) every viewmodel has it's model to return the encapsulated values from the model.

不过,我得在每一个视图模型模型属性。在CustomerViewModel的情况下,我将有一个参考的 CustomerViewModel ,一个在PersonBaseViewModel,一个在 BusinessObjectViewModel 作为同一个对象。这听起来很愚蠢的我。

But I got to have a Model property in every viewmodel. In the case of CustomerViewModel I would have a reference in CustomerViewModel, one in PersonBaseViewModel and one in BusinessObjectViewModel for one and the same object. That sounds stupid to me.

或者我必须投在上面的ViewModels每个属性的访问。

Or I have to cast every property access in the upper viewmodels.

P.S。这只是一小截出我的模型层次。

p.s. this is just a small cut-out of my model hierarchy.

在此先感谢。

推荐答案

如果BusinessObject的和Person类(和它们的VM对应)是抽象的,那么你可以像这样访问正确的型号:

If BusinessObject and Person classes (and their VM counterparts) are abstract, then you could access the right Model like this:

public abstract class BusinessObjectViewModel : ViewModelBase
{
    protected abstract BusinessObject BusinessObject { get; }

    protected BusinessObject Model { get { return this.BusinessObject; } }
}

public abstract class PersonViewModel : BusinessObjectViewModel
{
    protected abstract Person Person { get; }

    protected new Person Model { get { return this.Person; } }

    protected override sealed BusinessObject BusinessObject
    {
        get { return this.Model; }
    }
}

public class CustomerViewModel : PersonViewModel
{
    protected new Customer Model { get; set; }

    protected override sealed Person Person
    {
        get { return this.Model; }
    }
}

public class EmployeeViewModel : PersonViewModel
{
    protected new Employee Model { get; set; }

    protected override sealed Person Person
    {
        get { return this.Model; }
    }
}

这路的每派生VM类为价值其基本VM Model属性通过实施抽象属性和隐藏的基类Model属性,所以每一个虚拟机的工作原理与适当的类型(因此不需要铸造)的Model属性。

This way every derived VM class provides a value for its base VM Model property by implementing abstract property and hides a base class Model property, so every VM works with Model property of an appropriate type (so no casting is required).

这种方法有其优点和缺点:

This approach has its benefits and drawbacks:

好处:


  • 无铸造。参与

缺点:


  • 作品只有当基类(BusinessObjectViewModel和PersonViewModel)是抽象的,因为必须存在一个由派生类中实现,并提供了一个模型实例这些基类的抽象属性。

  • Model属性不应该在基类的构造函数来访问,因为构造函数链从基类变为最派生类。最派生类的构造函数将设置模式,所以基类构造函数的调用要及早地看到它。这可以通过传递模型通过构造一个参数是可以避免的。

  • 和BusinessObject的人物的属性是不必要的派生类可见。 EditorBrowsableAttribute可能会帮助这里的智能感知,但只有当代码是由不同的Visual Studio解决方案的另一个组件中使用(这是Visual Studio的具体行为)。

  • 性能。当基类访问模型,代码将通过虚拟财产链。但自从实施抽象属性被标记为封,虚表查找不应该这么多的性能下降。

  • 不能很好地扩展。对于深的类层次结构的代码将包含许多不必要的成员

  • Works only if base classes (BusinessObjectViewModel and PersonViewModel) are abstract because there must exist an abstract property that is implemented by the derived class and provides a Model instance to these base classes.
  • Model property should not be accessed in the base class constructors, because constructor chaining goes from base class to the most derived class. The most derived class constructor will set Model, so base class constructors are called to early to see it. This can be avoided by passing Model as a parameter through constructors.
  • BusinessObject and Person properties are unnecessary seen by the derived classes. EditorBrowsableAttribute might help here for Intellisense, but only when code is used by another assembly in different Visual Studio solution (this is Visual Studio specific behavior).
  • Performance. When base classes access Model, code will go through a chain of virtual properties. But since since implemented abstract properties are marked as sealed, virtual table lookup should not be so much performance degrading.
  • Doesn't scale nicely. For deep class hierarchies code would contain many unnecessary members.

另一种方法是:

public class BusinessObjectViewModel : ViewModelBase
{
    protected BusinessObject Model { get; private set; }

    public BusinessObjectViewModel(BusinessObject model)
    {
        this.Model = model;
    }
}

public class PersonViewModel : BusinessObjectViewModel
{
    protected new Person Model { get { return (Person)base.Model; } }

    public PersonViewModel(Person model)
        : base(model)
    {
    }
}

public class CustomerViewModel : PersonViewModel
{
    protected new Customer Model { get { return (Customer)base.Model; } }

    public CustomerViewModel(Customer model)
        : base(model)
    {
    }
}

public class EmployeeViewModel : PersonViewModel
{
    protected new Employee Model { get { return (Employee)base.Model; } }

    public EmployeeViewModel(Employee model)
        : base(model)
    {
    }
}

好处:


  • 基类并不需要是抽象的。

  • 模型可以通过基类的构造函数访问。

  • 没有不必要的额外属性。

缺点:


  • 铸造

在此基础上,我会去的第二选择,因为固定它唯一的缺点,铸造性能,是不必要的微观优化,不会在WPF背景下显着。

Based on this analysis, I would go with a second option because fixing its only drawback, casting performance, would be unnecessary micro-optimization that would not be noticeable in WPF context.

这篇关于视图模型继承和重复的模型引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆