3
votes

I have looked at a few threads discussing passing navigation objects between view models in MvvmCross, (e.g. here and here), and I wonder why MvvmCross doesn't have built-int support for serialization of complex types.

Let me clarify. If I have a navigation objects that consist of a CustomerName (string) and RecentPurchases (List) where Purchase type is a class with a few primitive type properties, then when I pass this navigation object to ShowViewModel, on the receiving side I will get a correct CustomerName and null for RecentPurchases. List is not recognized by MvvmCross as being simple enough for the serialization. This can easily be fixed by replacing RecentPurchases with SerializedRecentPurchases and assigning its value like this:

SerializedRecentPurchases = Mvx.Resolve<IMvxJsonConverter>()
                           .SerializeObject(RecentPurchases);

In a similar manner the string is deserialized in ViewModels' Init method.

It is all very simple, but I am a little puzzled why MvvmCross doesn't attempt to perform serialization saving developers from writing these lines of code again and again. I know we have to be careful about passing large amounts of data with navigation objects, but on the other hand it's quite common that navigation (or persistent state) objects may contain collections of simple complex types, so wouldn't it be more practical if MvvmCross supported this scenario out of the box?

1

1 Answers

8
votes

The reasons why "simple serialisation" for navigation was introduced in v3 were:

  • We wanted to remove the dependency of MvvmCross on any Json serializer - we love Json.Net and we love ServiceStack Text but we wanted people to be able to ship apps with neither of these if they wanted to
  • We intended that it would be easy to switch back to Json if people wanted to
    • this should be possible using just one line in setup - but there's a bug currently logged against this - see https://github.com/MvvmCross/MvvmCross/issues/450
    • even with that open bug, it's still easy to do with ~4 lines using a base class and code like that shown in your question or in the linked question
    • there are also ways that the simple serialisation should be extensible to more complex objects - but those are also linked to that 450 issue.
  • We wanted to make it more obvious to people that serialisation was taking place (it feels like 'why can't I pass an object' is an FAQ)
  • We wanted to try to discourage people from serialising large objects
    • because this is slow
    • and because WindowsPhone in particular has quite small limits on the size of the Xaml Uri that can be used (there is a .Net Uri limit of ~2050 characters, but beneath that I believe the WP limit is smaller still - about 1100 characters)

wouldn't it be more practical if MvvmCross supported this scenario out of the box?

Possibly - and that is the intention of the "1 line setup change" which https://github.com/MvvmCross/MvvmCross/issues/450 is currently blocking

There are some situations where passing complex list-based might be convenient - and there are several platforms which don't have the navigation limits of WindowsPhone.

To help with this, one of the key objectives of MvvmCross v3 was "Project CHIMP" also known as "CrossLight". The aim of CHIMP was to split MvvmCross apart into separate CrossCore, Binding, Mvvm and plugin layers - the idea being that this structure should make it easier for others to build their own app frameworks. Because of this, it should be easy for others now to provide alternative frameworks - perhaps including completely different navigation service patterns.

There's more on Project Chimp/CrossLight in:

However, within MvvmCross itself I personally would still recommend against passing large complex objects during serialisation - very few of my navigation objects are temporary so to me it generally "feels better" to pass keys to objects rather than the objects themselves.