2013-06-01 72 views
7

雖然在Pluralsight觀看有關MVVM視頻時出現了一種情況:MVVM模式得到了侵犯,但這樣做表現出的不正確的方法:顯示來自ViewModel的消息框是對MVVM的違反 - 如何避免?

  • 的觀點不得不使用ICommand的觸發的處理程序按鈕視圖模型。
  • 處理程序正確地將執行中繼到存儲庫實現。
  • 存儲庫的具體實現稱爲Web服務方法。

但是:如果Web服務調用失敗,ViewModel將彈出一個消息框,通知用戶有關錯誤。 由於ViewModel是視圖的抽象,它不應該直接創建UI,但是讓消息框呈現給用戶的100%乾淨的方式是什麼?

回答

9

創建服務:

interface IDialogService 
{ 
    void ShowMessageBox(string message); 
} 

實現:

class DialogService : IDialogService 
{ 
    public void ShowMessageBox(string message) 
    { 
     MessageBox.Show(); // ... 
    } 
} 

使用依賴注入:

class ViewModel 
{ 
    [Import] // This is MEF-specific sample 
    private readonly IDialogService dialogService; 
} 

或服務定位:

class ViewModel 
{ 
    private AnyCommandExecute() 
    { 
     // This is MEF-specific sample 
     var dialogService = container.GetExportedValue<IDialogService>(); 
    } 
} 

在您的視圖模型中獲取具體IDialogService,然後從ViewModel調用獲得的實現。

同樣的方法適用於任何其他類似的情況:顯示打開/保存對話框,顯示在對話框中輸入自定義視圖模式。

+0

看起來簡單,是有意義的。但是,如果我通過不實現ShowMessageBox()來實現ViewModel抽象,並且有一個用於單元測試的實現,另一個用於生產性用途,那麼我最終會得到沒有依賴注入的相同效果。對這種做法有何評論或批評? – Krumelur

+0

1)這違反了SRP。你讓視圖模型負責任何事情。 2)而不是2個服務實現(一個用於生產,一個用於測試),您應該保留每個視圖模型的2個實現,這需要這個功能。 3)考慮這一點:'SomeViewModel'需要顯示消息框,並且它具有抽象的'ShowMessageBox'; 'SomeDerivedViewModel:SomeViewModel'不需要顯示它,但是你已經有了這個方法。 – Dennis

5

有幾種方法可以做到這一點,堅持MVVM模式,如互動服務互動請求

互動服務

...可以通過視圖模型被用來啓動互動 與用戶,從而保持其對視圖的 實施

enter image description here

獨立服務

Interaction Request

...使用視圖模型引發的事件來表達 與用戶交互的意圖,以及視圖中綁定到這些事件並管理 交互的視覺方面的組件。

enter image description here

上述兩種引自這一來源(其還包含有關模式的更詳細信息):http://msdn.microsoft.com/en-us/library/gg405494(v=pandp.40).aspx#sec10