2014-10-18 37 views
0

假設有使用MVVM light工具包的WPF應用程序。MVVM定位器應該調用任何已註冊的ViewModel函數嗎?

這個工具包的好例子是定位器。 它包含SimpleIoC,它使我們能夠註冊服務併成爲接口驅動。

有時Locator構造函數可以真正增長。 可惜的是,除了註冊接口它包含了一些邏輯:

if(SimpleIoc.Default.GetInstance<MainViewModel>().LoadProject()) 
{ 
var project = SimpleIoc.Default.GetInstance<MainViewModel>().LoadedProject 
SimpleIoc.Default.Register<ConfigService>(new Service(project)) 
} 

這只是一個例子 - 如果我定位器構造過程中需要更多的邏輯。 也許我的服務體系結構是錯誤地創建的,因爲它們不是獨立的,或者在這種情況下,我應該辭去定位器的使用 - 但是我會丟失DI。

另一件事是,在少數ViewModels中有參考 Locator.GetInstance,我發現另一個不是一個好的做法,因爲它應該通過構造器注入來啓用可測試性。

另一個方面是正確使用AvalonDock。

AvalonDock是一款出色的可控制控件,可用於準備類似於Visual Studio等應用程序的應用程序,並具有可錨定的可停靠窗格。

此窗格實際上是通過屬性綁定到AvalonDock的另一個ViewModels。

MainViewModel具有屬性工具=新工具[] {ViewModel1,ViewModel2}

但是每個視圖模型是在定位器註冊。

因此我使用MainViewModel(違反DRY)他們爲

屬性的getter:Locator.GetInstance()

這在我看來是另一個壞榜樣 - 即使並不安全。 如果Avalon Tool ViewModel1所需的任何服務尚未註冊,但在MainViewModel實例化期間通過getter調用,會出現什麼情況。

它開始是不匹配的。你有什麼好的做法?

我發現很多例子,如工作區(MainViewModel),但沒有人在同一時間使用我發現非常有用的定位器。

我想保留定位器,因爲我認爲這是一件好事,它使得我的項目可以通過依賴注入和接口驅動進行測試。

任何意見建議?我會很感激。

回答

0

我會避免這種情況。正如你正確地指出的那樣,在這裏進行更多的事情,然後簡單地註冊類型。

相反,我會將ConfigService實例傳遞給ViewModel的構造函數。只要它是首先註冊的,您可以通過IOC配置服務和視圖模型。

SimpleIOC.Register<IViewModel>(()=>{return new ViewModel(SimpleIOC.GetInstance<IConfigService>())}); 

...這些都來自內存,所以可能不準確,但是顯示了來自SimpleIOC的自定義構造函數的想法。

在您的視圖模型構造函數中,您可以調用服務.Register方法將其自身作爲參數傳遞。

這樣可以保留視圖模型中的「知識」,而您的定位器仍然專注於做它應該做的事情。

相關問題