【问题标题】:MVVM Framework: PerformanceMVVM 框架:性能
【发布时间】:2015-06-05 17:45:06
【问题描述】:

我目前正在搜索我们将用于下一个应用程序的框架。目前我们有应用程序使用 winform 运行,我们计划慢慢切换到 WPF(使用新应用程序,然后重构 GUI)。我们是一个由 9 人组成的团队,致力于解决这个问题。

我们有一个大的解决方案(目前有 300 多个 VS 项目,大约 1'500'000 行代码),所以在选择框架时,我们正在寻找能够促进干净代码、良好基础架构的东西,但是也是一个不会减慢(太多)应用程序的框架。

目前,我主要对Prism(完全理解起来似乎有点复杂)和Caliburn.Micro感兴趣。

Caliburn.Micro 似乎更易于使用,但我有点担心所有这些面向约定的东西意味着很多事情将在运行时使用反射来完成。

我说的对吗?或者这是在编译时完成的?

我也不确定是否应该考虑 MVVM Light,因为它缺乏文档/目标应用程序大小。

【问题讨论】:

  • MVVM 不需要很快,因为它的操作往往不会迭代。别担心。就个人而言,我不喜欢约定俗成的方法。
  • 你可以试试MugenMvvmToolkit是一个跨平台的框架,也支持WinForms。它非常适合大型项目。文档不多,但例子很多。如果您对项目有任何疑问,我很乐意回答。
  • 您能否提供一些您认为会慢的示例(可能来自 Caliburn.Micro 文档)?到目前为止,我发现只有 ViewModelLocator 使用反射/约定,这不是你应该担心的事情
  • @Liero 例如:<ListBox x:Name="Products" /> 绑定到VM的“产品”属性,这必须使用反射来获取属性,对吧?
  • 好的,我不知道这一点,我永远不会这样做,但这不应该是性能问题。如果是这样,没有人说你必须使用这个约定。但这就是我不喜欢 mvvm 框架的原因。您说您希望 MVVM 框架会强制或指导您和您的团队以正确的方式组织代码,但通常 MVVM 框架为您提供了太多的方式,因为它们必须支持所有可能的情况。通过编写自己的组件(例如视图模型的基类、命令或导航等服务),您可以更好地控制团队。

标签: wpf mvvm prism mvvm-light caliburn.micro


【解决方案1】:

我已经使用 CM 几年了,从 1.1 开始。我是从棱镜过来的。虽然我同意其他海报的一些 cmets 和观点,但在这个阶段你真正唯一的选择是获取库/框架(无论你选择使用哪个),连接它并运行它一点点在你的主要项目的休息时间。在您的“付费时间”实施它可能没有什么好处,因为您在“实验”时无疑会遇到问题。

先做实验再做决定。想要分离关注点?想要快速发展?希望能够在工作区名称上放置一个控件并且它会正常工作(假设它具有内置约定,或者为第 3 方控件创建您自己的约定),将一些视图模型代码连接到一个属性或方法你命名了控件,然后试试 Caliburn.Micro。不想使用 Caliburn 的约定然后不要。 CM 的几乎所有内容都通过 Nuget 安装模块化以满足核心需求。

有许多 MVVM 框架和库都有不同的利基领域,有些是多平台的,有些是针对 1 个平台的。你只能使用你尝试过的东西,如果你发现你喜欢使用的东西并且它适用于你和你的团队,那么它(框架/库)就是应该定位的对象。

我离开 PRISM 的原因示例

在视图中

<Button x:Name="ClickMe" />

在视图模型中

public void ClickMe()
{
}

public string FirstName
{
  get{...}
  set
{
    _firstname = value;
    NotifyOfPropertyChange();
    NotifyOfPropertyChange( () => CanClickMe); )
}


public bool CanClickMe
{
    get { return !string.IsEmptyOrNull(_firstname); }
}

【讨论】:

  • 感谢您的反馈。是什么让你在 PRISM 之后离开 CM?
  • 已更新以显示我离开 PRISM 的原因的小 sn-p,这将需要 2 倍于已完成代码的代码,因为您需要创建一个带有执行和执行委托的 RelayCommand,然后传入必要的其他项目然后在 viewside 你需要设置 IsEnabled 和 Command 属性
【解决方案2】:

首先,Prism 不是 MVVM 框架。 Prism.MVVM 是一个非常轻量级的 MVVM 库,它独立于 Prism。

其次,这个 <ListBox x:Name="Products" /> 自动数据绑定到 viewmodel 在 Caliburn.Micro 中不应该是性能问题,因为 WPF 中的普通绑定无论如何都使用反射。不确定 Caliburn 是否也在内部使用反射,但即使这样做,如果您不在迭代场景中执行它,在运行时也几乎不会注意到,例如在 ItemsScontrol 中包含 1000 多个项目。如果您遇到性能问题,没有什么能阻止您以标准方式编写它。然而,它的附加价值是值得怀疑的。 IMO 它带来的问题多于解决的问题

如果我可以给你我的建议,请不要使用任何 MVVM 框架。您只需要INotifyPropertyChanged 实现和DelegateCommandICommand 实现)。在某些特殊情况下,您可能需要EventAggregator。现在告诉我,这三个类值得一个框架吗?不,不是。为什么要引入第三方库的依赖?

如果您要启动如此庞大的解决方案,编写自己的基类库的投资可以忽略不计。您始终可以从 Prism 获取一两个类的源代码,并在您自己的库中使用它们。

这些框架的问题在于,开发人员倾向于过度设计简单的场景,例如使用EventAggregator,其中普通事件甚至直接引用更合适。或者以 Prism 为例,他们在可以使用简单 ItemsControl 的地方使用区域和视图注入。

在使用 WPF 6 年之后,我成为 ViewModel-First 方法的大力支持者。 MVVM 然后变得简单得多。但大多数框架在使用 View-First 方法时效果更好。

所以,我的投票是不使用任何 MVVM 框架。如果必须使用一个,请选择 Prism.MVVM。看看源代码,写的不错。

【讨论】:

  • 我的印象是,使用框架将指导我们进行初始创建并为我们提供一个值得尊重的结构,这是一件好事,因为它是我们第一个使用 WPF 的“真正”项目。关于大项目:第一个应用程序将是一个小应用程序,由于目标是说服管理层慢慢迁移到 WPF,如果他们看到第一个应用程序的成本是双倍的,我不确定他们会不会很高兴。当您首先说 ViewModel 时,您的意思仍然是“在模型/业务之后”?
  • 从小型独立应用开始是明智的。在这种情况下,使用 Prism.MVVM 作为“模式和实践库”。它会引导你,这是真的。避免使用棱镜,它会引导你走错路。
  • viewmodel-first 是指比开发方法更多的视图和视图模型生命周期。例如看这个:stackoverflow.com/a/28916120/475727 它基本上说,首先你实例化视图模型,然后根据命名约定你实例化视图。就是这样。
  • 好吧我明白了,没想到它也用于导航。 Caliburn 采用这种方法,对吗?但是使用这种方法,如果我们为视图模型创建一个新视图,我们不能同时拥有两者然后切换到新的,对吧?
  • 这仅适用于页面。建议每个视图模型只有一个视图,反之亦然:practicalmvvm.com/Manifesto 它只是让事情变得更简单。而且您仍然可以使用继承来拥有相似的视图模型并实现最大的代码重用
【解决方案3】:

大多数 WPF 性能问题不是由 MVVM 框架引起的,而是由您如何实现 WPF 应用程序引起的(例如,您是否使用虚拟化列表?)。我认为您应该根据您的功能需求选择您的 MVVM 框架(是否所有功能都可用,例如命令实现、视图模型基类)。

更重要的是定义实现 MVVM/WPF 的约定和规则,并根据这些规则选择 MVVM 框架。一些约定和规则可以在my article about recommendations and best practices for implementing MVVM and XAML/.NET applications 中找到。

关于选择正确的 MVVM 框架有很多资源,例如:

【讨论】:

  • 我知道这不是导致性能泄漏的最重要原因,但它仍然对我们平衡我们使用的框架很重要。我的问题只是关于性能,正是因为所有其他资源(我已经阅读过)根本没有谈论这个。
  • 为了安全起见,您应该选择一个库(例如 MVVM Light)而不是框架(Caliburn),因为库不那么突兀,并且当您的应用程序的某些区域存在特定的性能问题时您仍然可以编写自己的代码而不使用该领域的库...
  • 我使用了 MVVM light,我喜欢它,我遇到的问题是我找不到任何文档、书籍、示例,它们显示了我可以使用的所有功能以及如何使用它。
猜你喜欢
  • 2012-05-28
  • 2011-08-09
  • 1970-01-01
  • 1970-01-01
  • 2010-12-23
  • 2013-03-15
  • 1970-01-01
  • 1970-01-01
  • 2011-05-28
相关资源
最近更新 更多