界面控件DevExpress WinForm - MVVM服務講解(一)

獲取工具下載 - DevExpress WinForm v21.2

考慮像顯示來自 ViewModel 的通知(例如,消息框)這樣的微不足道的任務,作爲可視化元素,任何消息框實際上都是視圖的一部分。 因此,如果你直接從 ViewModel 顯示消息框(定義一個調用 MessageBox.Show() 方法的命令),這個簡單的代碼將破壞主要的MVVM概念 - ViewModels不能引用Views,並使其無法編寫ViewModel的單元測試。爲了解決這個困難,DevExpress MVVM 框架實現了服務。

服務是一種 IOC 模式,它刪除了 ViewModel 和 View 層之間的任何引用。 在代碼中,服務是在 ViewModel 代碼中使用的接口,沒有任何關於“何時”和“如何”實現該接口的假設。

您可以實現自己的自定義服務以及使用 DevExpress Services,無論您使用什麼服務,通用工作流程都保持不變:

  • 在代碼中定義服務(如果您使用的是 DevExpress 已經實現的服務,則跳過);
  • 在特定的視圖中註冊它;
  • 在ViewModel中檢索服務並使用其方法。

DevExpress Services

DevExpress MVVM框架已經爲大多數常見任務提供了現成的服務——顯示消息、彈出窗口、對話框、添加應用程序 UI 管理器文檔等。例如,以下 ViewModel 代碼通過定義 IMessageBoxService 類型的屬性來檢索 XtraMessageBoxService。

C#

//ViewModel
public class MyViewModel {
protected IMessageBoxService MessageBoxService {
get { return this.GetService<IMessageBoxService>(); }
}
}

VB.NET

'ViewModel
Public Class MyViewModel
Protected ReadOnly Property MessageBoxService() As IMessageBoxService
Get
Return Me.GetService(Of IMessageBoxService)()
End Get
End Property

重要提示:GetService方法不是線程安全的,不應從後臺線程調用。

對於 POCO ViewModel,您可以使用以下故障安全語法,該語法將自動使用 this.GetService 方法或在出現問題時引發異常。

C#

//POCO ViewModel
protected virtual IMessageBoxService MessageBoxService {
get { throw new System.NotImplementedException(); }
}

VB.NET

//POCO ViewModel
Protected Overridable ReadOnly Property MessageBoxService() As IMessageBoxService
Get
Throw New System.NotImplementedException()
End Get
End Property

檢索服務後,您可以在 ViewModel 中使用其方法:

C#

public void SayHello() {
MessageBoxService.Show("Hello!");
}

VB.NET

Public Sub SayHello()
MessageBoxService.Show("Hello!")
End Sub

最後,在視圖中註冊您的服務。 服務要麼註冊在本地容器中以在單個 View 中使用(本地服務),要麼註冊到允許您在整個應用程序中使用註冊服務的全局靜態(單例)服務容器(全局服務)。

C#

//Global service
DevExpress.Mvvm.ServiceContainer.Default.RegisterService(new SomeService());
//Local service
serviceContainer.RegisterService(new SomeFilterService(ModuleType.MyCustomFilter));

VB.NET

'Global service
DevExpress.Mvvm.ServiceContainer.Default.RegisterService(New SomeService())
'Local service
serviceContainer.RegisterService(New SomeFilterService(ModuleType.MyCustomFilter))

當創建 ViewModel 時,服務也可以在運行時在服務容器中註冊。

C#

this.ServiceContainer.RegisterService(new Services.AnotherService());

VB.NET

Me.ServiceContainer.RegisterService(New Services.AnotherService())

最後,您可以通過在此級別提供自定義服務實現來覆蓋 ViewModel 層次結構中任何級別的父級服務實現。

C#

serviceContainer.RegisterService(new NotImplementedCustomService(ModuleType.MyMainView));

VB.NET

serviceContainer.RegisterService(New NotImplementedCustomService(ModuleType.MyMainView))

使用 MvvmContext 組件,您無需記住這個底層服務容器機制。 該組件的 API 提供了易於使用的方法來註冊全局和本地級別的服務。

C#

//Static method that registers the global DevExpress XtraDialogService
MVVMContext.RegisterXtraDialogService();
//Registers the Service1 service in the default service container (global service)
mvvmContext1.RegisterDefaultService(new Service1());
//Registers the local Service1 for use within the current View only
mvvmContext1.RegisterService(new Service2());

VB.NET

'Static method that registers the global DevExpress XtraDialogService
MVVMContext.RegisterXtraDialogService()
'Registers the Service1 service in the default service container (global service)
mvvmContext1.RegisterDefaultService(New Service1())
'Registers the local Service1 for use within the current View only
mvvmContext1.RegisterService(New Service2())

許多隨時可用的服務已經在全局靜態容器中註冊,因此您甚至不需要手動註冊它們。 刪除 MessageBox 服務演示中的 RegisterMessageBoxService 方法調用,您會注意到該服務仍在工作。

如果需要,您可以重新定義這些服務註冊,爲此請使用 MVVMContext 類的相應靜態 Register... 方法。 例如,XtraMessageBox Service 和 FlyoutMessageBox Service 示例的 ViewModel 與第一個示例的 ViewModel 相同。 所有三個 ViewModel 都檢索實現 IMessageBoxService 的服務,但是使用不同的靜態 Register... 方法會強制使用不同的服務。

相同的方法允許來自 Dialog Services 組的示例顯示不同的對話框,儘管 ViewModel 代碼是相同的。

C#

protected IDialogService DialogService {
get { return this.GetService<IDialogService>(); }
}

VB.NET

Protected ReadOnly Property DialogService() As IDialogService
Get
Return Me.GetService(Of IDialogService)()
End Get
End Property

由於註冊不同服務的視圖代碼而調用不同的對話框。

C#

//XtraDialog service
MVVMContext.RegisterXtraDialogService();
//FlyoutDialog service
MVVMContext.RegisterFlyoutDialogService();

VB.NET

'XtraDialog service
MVVMContext.RegisterXtraDialogService()
'FlyoutDialog service
MVVMContext.RegisterFlyoutDialogService()

DevExpress WinForm | 下載試用

DevExpress WinForm擁有180+組件和UI庫,能爲Windows Forms平臺創建具有影響力的業務解決方案。DevExpress WinForms能完美構建流暢、美觀且易於使用的應用程序,無論是Office風格的界面,還是分析處理大批量的業務數據,它都能輕鬆勝任!


DevExpress技術交流羣5:742234706      歡迎一起進羣討論

更多DevExpress線上公開課、中文教程資訊請上中文網獲取

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章