介紹一個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,其中固然以有對工廠的依賴。