And*_*dre 4 c# wpf mvvm mvvm-light entity-framework-6
许多人建议WPF MVVM开发人员不要将Model实例从ViewModel暴露给View.要显示模型实例集合中的信息,请将所有单个项目包装到ViewModel实例中,并将ViewModel集合公开给View.
但是,使用MVVM Light在我看来有两种ViewModel:
MainWindowViewModel或CustomerEditorViewModel).假设只有一个MainWindow,只有一个MainWindowViewModel.CustomerViewModel)具有一对一关系的ViewModel,是模型实例的某种"机制套装",提供计算属性等附加功能(例如Durationfrom StartTime和EndTime).一个普通的公司有很多Customers所以会有很多CustomerViewModels.那么如何包装Model实例呢?
一个想法可能是创建包含ViewModelBase但不注册和实例化那些的包装类ViewModelLocator.我认为两个单独的东西都叫做ViewModel并不是一个好主意.
另一个想法可能是为第二种类型的ViewModel使用新的基类,也许可以调用ModelInfo.在单个实例中MainViewModel,将存在一组CustomerInfo实例,为Customer模型数据提供附加功能.
我倾向于后者,但因为这似乎是使用MVVM Light的一般情况,我相信必须有一个共同的解决方案来解决这个问题.
更新
我找到了 MVVM Light的作者Laurent Bugnion的一篇文章.在他2012年的文章中,Bugnion使用两种不同的方法来初始化ViewModel:
MainViewModel是注册的ViewModelLocator,没有构造函数参数.因此它适用于依赖注入,可以通过ServiceLocator实例化.FriendViewModel未注册,ViewModelLocator并且其构造函数将Model实例作为参数.它不能使用ServiceLocator进行实例化,而只能通过直接调用构造函数并传递模型实例来实例化.这几乎与我原始问题中提到的差异一致,并且第一个想法是如何包装模型实例.
这是我个人7年的MVVM经验.我说个人是因为你会发现很多关于这个话题的矛盾,特别是当你参考官方的MSDN定义时
"在我看来,有两种ViewModels"
绝对不是,但这是一个常见的误解.ViewModel的第一个角色是View的可测试和可维护的表示.然后,正确的抽象是与您的视图的一对一关系,而不是您的模型.
"许多人建议WPF MVVM开发人员不要将Model实例从ViewModel暴露给View."
是的,它仍然是正确的,因为如果从OOP角度正确实现模型,则将责任和业务逻辑放在其中.因此,您的ViewModel只是INotifiedPropertyChanged,并包含您希望从模型中公开的信息,以及要在模型中调用的命令.
经典解释(包括MSDN的解释)是不完整的,因为它假设您可以将一个View与一个ViewModel与一个Model对齐.因此,您的问题经常被忽视,因为在非常简单的CRUD系统中,您可以轻松实现这种一对一的关系.建立这种关系的另一种方法是使用CQRS,因为它允许您生成一个没有任何逻辑的模型,并直接在您的视图上对齐以进行查询.
但正如您已经体验过的那样(如果您不使用CRUD或CQRS系统),在大多数经典实现中,您的ViewModel代表您的View,但需要多个模型才能正常工作(这非常自然).您必须在这些模型中添加尽可能多的业务逻辑.为了管理对不同模型的调用之间的流程,您可以添加另一个抽象,可以称为服务.此服务应代表业务案例,需要使用多个模型.
您可以通过这种方式考虑它:您的BusinessService应独立于基础架构工作.它不应该关心它是从ViewModel调用还是从Web应用程序中的Controller调用.它只是管理一些模型之间的流程,以满足业务需求.
让我试试一下:
ViewModel不应该有业务逻辑(但你已经得到了)
ViewModel是View的抽象(而不是您的Model的抽象,即使在某些情况下您可以获得一对一的关系)
如果ViewModel需要多个模型来满足业务需求,请使用服务来管理不同模型之间的流程(根据定义,它变为BusinessService)
这是一篇博客文章,其中包含代码示例以澄清我的观点:http: //ouarzy.azurewebsites.net/2016/04/14/clarifying-mvvm-with-ddd/
希望能帮助到你.
| 归档时间: |
|
| 查看次数: |
785 次 |
| 最近记录: |