上一次寫MvvmLight框架使用入門(4)的時候還在用Visual Studio 2015,我兒子也不會過來蓋上我的XPS……重啟這個系列一方面是因為最近又開始寫UWP的東西了,另一個是因為MvvmLight支援.NET Standard後,在使用上發生了一點小變化。在連續被問了幾次
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
的相容性問題後,我決定去調查一下事情的真相。
首先我們去Github上確認一下MvvmLight的最新版本。
https://github.com/lbugnion/mvvmlight
作者可能覺得沒有什麼挑戰了,更新相對不再頻繁。這兩年最重大的改變就是對.NET Standard的支援。我們可以看到MvvmLight分為以下幾個版本:
- MvvmLightLibs和MvvmLight可以認為是同一個庫,唯一不同後者會包含ViewModelLocator之類的幫助類。這兩個庫適用於WPF(.NET Framework)和UWP project。
- MvvmLightAndroidSupport沒用過不敢亂講,略過。
- MvvmLightLibsStd10和MvvmLightStd10也基本相同,增加了對.NET Standard的支援。這兩個庫適用於WPF(.NET Framework),WPF(.NET Core)和UWP project。
這裡有兩點值得注意:
- 只有WPF(.NET Framework)工程,才能通過MvvmLight或MvvmLightStd10,如願生成ViewModelLocator,MainViewModel等幫助類。
- Std10版本的MvvmLight,不再依賴CommonServiceLocator。所以從舊有程式碼升級的專案,會遇到一個相容性的問題。
那麼如何修復這個問題呢?從MvvmLight的原始碼來看,在支援.NET Standard的分支上,SimpleIoc這個類已經不再繼承IServiceLocator介面。也不再通過
ServiceLocator.Current.GetInstance<MainViewModel>();
來獲取物件的例項,而是直接通過
SimpleIoc.Default.GetInstance<MainViewModel>();
來實現相同的功能。所以我們只要簡單的刪除報錯的這句:
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
同時將之前使用ServiceLocator的程式碼修改如下即可:
public MainViewModel Main { get { return SimpleIoc.Default.GetInstance<MainViewModel>(); } }
我們再來說下VSIX packages的問題,從Github頁面的issue來看,作者提交過VS2019的版本,可能因為VS2019版本更新頻繁,和最新版發生衝突又被下架了。相信作者後續會再更新上去,畢竟issue裡有那麼多人在不停的問這個事情。
其實VSIX也不是必須的,我通常都是通過Nuget新增MvvmLight的引用,而不是使用VSIX,所以這個問題影響不大。
最後總結一下MvvmLight在2020年的推薦使用方式:
- 使用MvvmLightStd10在WPF(.NET Framework)工程
- 使用MvvmLightLibsStd10在WPF(.NET Core)和UWP 工程。
- 可以儲存生成好的ViewModelLocator等檔案,拷貝到WPF(.NET Core)和UWP工程中使用。
之前的篇章在介紹MvvmLight時並沒有在Github上建立sameple project。這次一併補上:
https://github.com/manupstairs/MvvmLightSample
後續會把這個系列補完,絕不太監……