C# MVVM-模式和实用性

C# MVVM-模式和实用性,c#,wpf,mvvm,C#,Wpf,Mvvm,我已经在WPF中使用MVVM有一段时间了。在开发过程中,我学到了很多东西(从从不使用它到在其中开发几个应用程序) 然而,最近我有一些针对代码的评论,这让我怀疑我是否以正确的方式做事。我当前的设置(大致)如下: 模型-负责存储数据,使用 IDataErrorInfo和脏跟踪 ViewModel-负责获取数据(来自存储库,如 模式)并将其格式化以供视图使用(例如 过滤、排序)还负责从 查看(保存、加载、筛选更改等) 查看-常见的UI内容 现在有人向我提到,我应该永远不要在模型中包含业务逻辑,并且

我已经在WPF中使用MVVM有一段时间了。在开发过程中,我学到了很多东西(从从不使用它到在其中开发几个应用程序)

然而,最近我有一些针对代码的评论,这让我怀疑我是否以正确的方式做事。我当前的设置(大致)如下:

  • 模型-负责存储数据,使用 IDataErrorInfo和脏跟踪
  • ViewModel-负责获取数据(来自存储库,如 模式)并将其格式化以供视图使用(例如 过滤、排序)还负责从 查看(保存、加载、筛选更改等)
  • 查看-常见的UI内容
现在有人向我提到,我应该永远不要在模型中包含业务逻辑,并且模型应该尽可能精简,viewmodel应该负责处理数据验证和脏跟踪之类的事情

我已经看到了这两方面的评论和批评,有人反对,也有人反对在模型中加入逻辑,我还没有看到这些笼统声明的任何实际原因。所以我很想知道我重构我的设置是否有真正的原因

此外,考虑到我将逻辑移到了viewmodel,我可以看到在当前有一个viewmodel的情况下有多个viewmodel的需要,例如:

  • 人员
    -型号
  • PersonViewModel
    -处理脏跟踪、数据验证等
  • PersonViewModel
    -处理获取PersonViewModels集合, 过滤等
  • PersonView
    -用户界面

这似乎有点多余,但也许我误解了什么。我真正寻找的是这样或那样做的一些实际原因,或者如果这是另一个论点,比如在MVVM中使用代码隐藏(纯粹的观点,没有什么理由等)

你的问题没有简单的答案。最简单的答案是模型和视图模型应该包含您应该进行单元测试的代码。模型和视图模型之间的分离不太明显。我喜欢使模型尽可能简单,并将其限制在与服务器层交换的任何内容上。视图模型应该封装模型,并提供任何附加功能(业务逻辑和抽象表示逻辑),以便您可以使表示层尽可能简单(在WPF XAML的情况下是声明性的)。

我喜欢将模型层视为与应用程序的托管方式无关的任何东西(即独立于WPF)。它是一个或多个DLL,表示业务领域以及需要在其中执行的操作。如果将这些DLL用于web应用程序windows service e.t.c是有意义的,则通常表明模型和ViewModel之间的拆分是适当的。

我这样看:

模型-可以传递的对象。不同层之间用于通信的通用类型

ViewModel-专门为视图创建。这里应该包含UI逻辑,例如,数据注释等。您也可以在这里调用web服务方法(假设您的实际业务逻辑位于门面层,或者您的数据库逻辑位于不同的层/项目中)要填充视图、下拉列表等,根据您的设计,每个视图可能会有这些视图的倍数

仅查看用户界面


我不怕在ViewModel中加入外部调用,MVVM的高级描述:

  • 视图:用户界面

  • 模型:业务逻辑和数据(例如域模型+存储库,或事务脚本+POCO实体等)

  • ViewModel:以这种形式向视图公开的数据,这种数据很容易从视图中使用。Wikipedia的定义是:视图模型是视图的抽象,它公开公共属性和命令

我喜欢()原则:简单性、可混合性、可设计性、可测试性

这是一个非常高层次和抽象的描述,这就是为什么你可能会发现MVVM有很多变化。无论你选择什么MVVM风格,记住责任和原则,你应该可以。尽量避免复杂性。MVVM不是银弹,你不能用单一的设计模式涵盖所有场景。一个MVVM实现n可能适用于一个应用程序,但不适用于另一个应用程序。例如,我为每个新项目从头开始构建我的mvvm体系结构,以确保最适合


说到责任:

以验证为例: 密码和重复密码输入应该相等的验证逻辑显然是表示逻辑,应该存在于viewmodel中。另一方面,可能存在业务规则,密码必须至少包含一个特殊字符。此逻辑应该存在于模型中,但您可以在viewmodel中公开它,以便从中轻松使用视图。这是一个业务逻辑,但您可能需要以某种方式展示它

如果您的应用程序只使用webservice进行检索和存储,那么您的模型可能只是数据访问组件


以下是一些资源:

维基百科:

MVVM是Martin Fowler MVP模式的变体,您可能会发现它也很有用:


MSDN(模式与实践):

您喜欢保持模型精简的事实仅仅是一种个人选择吗?这是否意味着我对多视图模型的假设是您选择的做事方式?这是个人选择和对该主题的研究的混合。是的,我经常对单个模型使用多视图模型-视图m