MVVM模式解析和在WPF中的實現(六) 用依賴注入的方式配置ViewModel並註冊消息

MVVM模式解析和在WPF中的實現(六)

用依賴注入的方式配置ViewModel並註冊消息

系列目錄:html

MVVM模式解析和在WPF中的實現(一)MVVM模式簡介git

MVVM模式解析和在WPF中的實現(二)數據綁定github

MVVM模式解析和在WPF中的實現(三)命令綁定框架

MVVM模式解析和在WPF中的實現(四)事件綁定函數

MVVM模式解析和在WPF中的實現(五)View和ViewModel的通訊 學習

MVVM模式解析和在WPF中的實現(六)用依賴注入的方式配置ViewModel並註冊消息測試

0x00 最初的想法

此次主要討論下給View指定ViewModel的事情。通常來講給View指定ViewModel經常使用的方式有兩種,一種是在View的後臺代碼中寫DataContext = new ViewModel(),還有一種是在XAML中指定View的DataContext。這兩種方式都使得View對ViewModel產生了依賴,這種狀況下能夠考慮用依賴注入的方式使取消View對ViewModel的直接依賴。依賴注入通常來講能夠經過構造函數注入、經過設置屬性注入,這兩種方法對於View來講都不合適。所以可使用IoC Container,讓View主動去獲取對應的ViewModel。this

其實給View指定一個ViewModel並不屬於頻繁的操做,並且改起來也很容易,費半天勁搞個依賴注入確實不太至於。就像上篇文章中廢了半天勁搞了個View和ViewModel的通訊同樣,用到的機率比較小,並且也有別的方式解決,雖然那種方式並不符合MVVM模式。不過View除了依賴ViewModel以外對消息註冊器也是會產生依賴的,並且某種類型的View通常來講都依賴固定類型的ViewModel和消息註冊器,所以能夠一次注入兩個依賴,這樣貌似就值了,至少我認爲是值了,因此有了ViewModelManager這個類。spa

0x01 ViewModel和MessageManager的依賴注入

使用靜態類ViewModelManager來看成IoC Container。往IoC Container裏註冊依賴關係通常有兩種方式,一種是將依賴關係以某種形式(例如xml)保存在外部,一種是在程序中註冊到一個列表裏。我採起第二種作法,由於比較容易:)xml

程序在啓動時使用ViewModelManager.Register將依賴關係註冊到ViewModelManager中,View在構造函數中調用ViewModelManager.SetViewModel(this);來設置View的DataContext並經過依賴的消息註冊器註冊消息,消息註冊器能夠爲空,表明View不接收消息。它們的關係如圖所示:

 

須要說明的有兩個地方:

一個是View和ViewModel的對應關係。通常來講一個View對應着一種ViewModel,這樣註冊起來是沒問題的。但這個並不絕對,理論上來講一個View能夠將DataContext設置爲任意ViewModel,若是一個View能夠設置多種ViewModel該如何處理呢,這時候能夠在ViewModelManager註冊時添加Token屬性,而後用SetViewModel(this,token)的方式指定特定的ViewModel爲DataContext。

另外一個是消息註冊的範圍。由於通常來講ViewModel都是和綁定的View通訊。因此默認狀況下,消息註冊到單獨一個MessageManager中,這個MessageManager保存ViewModel中,ViewModel使用這個MessageManager發送消息,發送的消息由View接收。但若是須要和其餘View通訊,須要把消息註冊到MessageManager.Default中,這個對象是static的,要達到這個目的只要在View設置ViewMode時這樣來SetViewModel(this,isGlobalMsg:true)便可。若是ViewModel又想和綁定的View單獨通訊,有時候還須要和別的View通訊,能夠在消息註冊器中註冊時將須要單獨通訊的消息設置一個Group,ViewModel在發送消息時加一個Group過濾一下便可。一個Group能夠理解爲消息的單獨一個通道。

順帶一提,好吧只是順帶一提的是,在給View注入ViewModel時,順便把ViewModel的UIDispatcher屬性設置爲了View的Dispatcher,雖然我不知道這有什麼用。但這樣在ViewModel中使用UIDispatcher時即爲相關的View的Dispatcher。若是要使用MainWindow的Dispatcher能夠經過DispatcherHelper.Dispatcher或者App.Current.MainWindow.Dispatcher得到。

0x02 寫在最後

到此爲止我能想到的MVVM框架的功能算是基本實現了,遇到的需求十分有限,才能也十分有限,能想到的就這幾個了,歡迎回復討論,也歡迎加我QQ16141860交流。以前一直是在TestArea這個倉庫裏進行測試,如今這個小框架整理了下,放到AyxMVVM倉庫裏了。如今有些想法還不太成熟,使用過程當中遇到問題也會隨時修正,之後就都修改到AyxMVVM中了,TestArea中的MyMVVM再也不維護了。另外給倉庫起名真是件麻煩事,乾脆統一都用Ayx+XXX的方式,這樣既容易重複的機率又十分小。Ayx是我名字拼音的首字母,想一想看以拼音A開頭的姓氏之少就能想到幾乎不會出現重複了。最後,10月6日看了微軟的秋季產品發佈會後信仰充值成功。對UWP十分感興趣,下一步打算學習一下。

0x03 關於AyxMVVM

https://github.com/durow/AyxMVVM

 


更多內容歡迎訪問個人博客:http://www.durow.vip

相關文章
相關標籤/搜索