Upgrading from Mvvmcross 5 to Mvvmcross 6.2

Benjamin Mayrargue
Jun 9, 2018 · 5 min read

Mvvmcross 6 is a new version of Mvvmcross using Netstandard2 instead of the obsolete PCL libraries. It is also a complete refactoring of the previous versions. Migrating is not as easy as updating nuget. But to prevent further technical debt, you should migrate as soon as possible.

Migration Overview

  • Upgrade your PCL projects to netstandard2
  • Replace all the calls to Mvx.Log (already available in 5)
  • Upgrade all your in-house Mvvmcross 5 plugins to 6
  • Replace all Mvvmcross 5 nugets and plugins in all your projects
  • Fix namespaces and class names
  • Fix startup
  • Fix ios project
  • Fix android project

Upgrade your PCL projects to netstandard2

This is the real first step to take. If you still have a PCL project, you own a 2 years technical debt. So first convert your project to netstandard2.

The same is true for projects containing a package.config file. Migrate these “package.config” projects to “PackageReference” projects. VS2017 now includes a wizard for this: right click on the package.config file and migrate.

A project’s csproj file after package.config is removed

Replace all the calls to Mvx.Log (already available in 5)

The logging infrastructure has changed in Mvvmcrss 5, but it keeps the compatibility with Mvx.Log. Mvvmcross 6 removed this compatibility. So make sure you use the new logging system everywhere first.

Note that there is no equivalent of the static method Mvx.Log. Instead you should call Mvx.Resolve<IMvxLog>().Trace() for example.

At this point, your apps should still compile and run fine.

Upgrade all your in-house Mvvmcross 5 plugins to 6

All your Mvvmcross plugins must use Mvvmcross 6, otherwise bad things will happen at runtime. So the first step is to upgrade them. Use this same guide to do it:

  • Replace all Mvvmcross 5 nugets and plugins from the solution (see next chapter)
  • Remove calls to PresentModalViewController()/NativeModalViewControllerDisappeared as the interface has been removed. Instead you’ll have to manually find a UIView/Activity on which you can attach. This is a real issue with this mvvmcross 6 version, as the code used in the existing plugins is failing in case your app already displays a dialog or a UIAlert window. Here a working code for iOS:

For Android, inherit your plugin from MvxAndroidTask and use base.StartActivityForResult().

Replace all Mvvmcross 5 nugets and plugins from the solution

You should do this in 2 steps: remove all nugets, then add the new ones.

To remove the nugets, you can use the nuget package manager, but it’s much faster to edit the csjproj files by hand and remove the entries. Don’t forget a project, and don’t forget a plugin.

Then use the package manager to add the new Mvvmcross 6 nugets. Note that you now only need a few packages. Most used packages are:

  • Mvvmcross
  • Mvvmcross.Plugin.Messenger

Fix namespaces

This is the most annoying part. Mvvmcross 6 renamed nearly all namespaces. So lots of “using” lines will be obsolete. In nearly 100% of your source files. Do this one project at a time. Start with the netstandard projects. Finished with the platform projects. After this operation, each project should compile fine.

This will be a pain to change unless you use the Resharper extension. Resharper shows in red the old namepaces (missing), and automatically pops a tooltip to add “missing namespaces” in one single click. Amazing.

Resharper in action

Fix things

Mvx.IocConstruct has been renamed Mvx.IoCConstruct

IMvxMainThreadDispatcher is obsolete and replaced by IMvxMainThreadAsyncDispatcher. The InvokeOnMainThread method is replaced by ExecuteOnMainThreadAsync() which returns a Task.

MvxViewModel contains a new property “Log” of type ‘IMvxLog’. But it requires that the virtual LogProvider property is initialized.

Fix startup

In App.cs, the correct place to navigate your first viewmodel is in your custom MvxAppStart in the NavigateToFirstViewModel() method. In this method use the NavigationService property.
You should not navigate a viewmodel directly in the App.cs’s Initialize() method.

Inherit either from MvxAppStart<YourViewModel>, or from MvxAppStart and override NavigateToFirstViewModel() and register it in you app’s constructor:

Note that this interface has a new method, ResetStart(). On Android, it must be called manually in response to Application.IActivityLifecycleCallbacks.OnActivityDestroyed when the destroyed activity is the root activity of your app (ie: activity.IsTaskRoot is true and typeof(activity)=typeof(yourmainactivity).

Fix iOS project

Remove the boostrap folder (and all bootstrap files). These are not needed anymore.

These special classes needs specific changes if you customized them:

  • AppDelegate.cs
  • Setup.cs (if you use a custom one)
  • AppPresenter.cs (if you use a custom one, even if it compiles)

for AppDelegate.cs:

  • The FinishedLaunching method should not do any custom ini anymore, other than google/firebase and facebook. Move this to InitializePlatformServices in setup.cs.
  • If you use a custom Setup class, register it in the new override:

for Setup.cs:

  • CreatePresenter has been renamed to CreateViewPresenter.
  • InitializePlatformServices is now the only method that runs on the UI thread. All other methods runs on a background thread. Make sure you do UIKit calls only on the UI thread. Especially calls to get the screen size, initialize your app’s theme, but also initialize the Azure AppCenter’s libraries!
  • If you need to manually register/initialize plugins or converters, override LoadPlugins(IMvxPluginManager)in App.cs instead.

for AppPresenter.cs:

  • PresentModalViewController()/NativeModalViewControllerDisappearedOnItsOwn have been removed from IMvxTouchViewPresenter.

Fix Android project

Things are quite the same as in iOS, except that :

  • If you have a custom android Application class, it must either inherit from the new MvxAndroidApplication class, or your Setup.cs class must override InitializeAndroidCurrentTopActivity and IMvxAndroidCurrentTopActivity should be registered in the IOC.
  • The MvxAndroidApplication class has a default RegisterSetup method which calls this.RegisterSetupType<Setup>(typeof(Setup).Assembly); This will initialize the Setup.ViewAssemblies property (which is the list of assemblies where mvvmcross search the views).

Replace all calls to Mvx.Resolve, Mvx.Register and related methods

This is optional as it will only generate warnings (for now).

All these methods have moved into a new container for objects (ioc) and are now accessible through Mvx.IoCProvider.Resolve<T> for example.

Good luck

You can check other changes on the mvvmcross migration document which completes points not covered by this article: https://www.mvvmcross.com/documentation/upgrading/upgrade-to-mvvmcross-60

Happy coding !
Benjamin Mayrargue, VAPOLIA.

Note: see our fantastic XamSvg and WheelPicker nuget libraries for Xamarin and Forms!

Benjamin Mayrargue

Written by

https://www.linkedin.com/in/benjaminmayrargue/

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade