介绍一个Prism的MVVM实现,主要介绍Prism如何在WPF上进行的一些封装,以实现MVVM。MVVM究竟是什么呢?看一下这一幅经典的图数据库
之前没有ViewModel这个概念,就是将Model传递到View显示,这样软件也能够工做,但却很混乱,一旦VIew要改动,一点点的改动都会形成不少代码须要改动,不利于维护。再者VIew层充斥着各类解析Model的代码,这些代码彻底不属于View啊。无缘无故的给View增长了不少职责。这是坏代码的味道。因此就有了ViewModel。ViewModel负责干什么,必需要干什么,其实ViewModel的职责就是将本身的数据绑定到View显示,同时数据变化须要通知View,View上客户的操做及时响应,至于数据怎么解析,从哪里获取,View的响应都应该方法后一层,能够是Controller,能够是Servicer,能够是Presenter。也就是业务逻辑尽可能推到后一层。设计模式
试想一下,系统里的Model有不少,有数据库对应的数据库模型,有业务于对应的领域模型,有用于数据交互的DTO也是模型,那么对应的View有一个ViewModel也不以为奇怪。框架
MVVM的第一步就是要解决ViewModel的依赖注入问题,框架如何不着痕迹的将View对应的VIewModel注入到依赖属性DataContext。ide
还记得PrismApplicationBase类吗,就是继承Application,将整个Prism框架组件注入到Unity的那个类,设计
看到第一步是啥?ConfigureViewModelLocator,配置ViewModelLocator,急人之所急,Prism框架的第一步配置ViewModelLocator,3d
好吧,第一步就是设置ViewModelFactory,这个工厂就是经过View的类型和实例从Unity容器中获取ViewModel实例。blog
噢!这个View参数还没用上。继承
再来看看这个包含ViewModelFactory的ViewModelLocationProvider。it
从这个名字咱们能够大胆猜想,这个类应该是负责真正解析ViewModel的位置的,看到这个类的方法,有ViewModelFactory,有Register,有GetViewModelByXXX。io
这个类中一个委托字段_defaultViewTypeToViewModelTypeResolver,从这个字段咱们能够看出是默认VIewModel解析方式,能够看出就是把View完整类型名中的Views替换成ViewModels,而后返回Type,从这里面咱们知道View的名字必定要含有Views,ViewModel必定要含有ViewModels。
好吧,知道了哪里解析的再来看看哪里调用的。
prism:ViewModelLocator.AutoWireViewModel="True",看到了,将ViewModelLocator的依赖属性AutoWireViewModel至为True,能够进一步推测ViewModelLocator里面确定调用了ViewModelLocationProvider的相关方法以得到ViewModel的类型或实例。
依赖属性改变触发了AutoWireViewModelChanged方法,而后调用ViewModelLocationProvider.AutoWireViewModelChanged
先去查看两个字典,一个字典key是View是实例,另外一个字典key是View的Type,都没有调用,而后调用ViewModelLocationProvider._defaultViewTypeToViewModelTypeResolver,也就是默认解析,在这边解析得到VIewModel的类型,而后经过默认工厂得到ViewModel实例。并绑定到VIew的DataContext。
至此,知道了整个默认VIewModel解析的所有过程,梳理一下
经过0的介绍,想一下怎么自定义实现VIewModel定位,有几种方法,
这个例子用的是第二种。
在程序的开始重写ConfigureViewModelLocator方法,除了向ViewModelLocationProvider中添加ViewModelFactory外,还修改了_defaultViewTypeToViewModelTypeResolver解析方式。直接就经过View的type后面家长ViewModel,简单粗暴。
这种方法就是上面提到的1方法
这张方法显然有很大的弊端,当程序中有不少View时怎么能手动添加呢,只能适用与特殊的View和ViewModel的解析,如Shell的VIewModel的解析。
这种解析方法也不用在乎View和ViewModel的名字了。
从ViewModel的解析中,咱们看到一种设计模式,View依赖ViewModelLocator,ViewModelLocator依赖ViewModelLocationProvider,ViewModelLocationProvider负责具体解析出对应的实例,至关于ViewModelRegistry,其中固然以有对工厂的依赖。