上一次写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
后续会把这个系列补完,绝不太监……