Monday, May 14, 2012

Portable Class Libraries in MvvmCross vNext


The first version of MvvmCross provided an excellent way to share ViewModel, Model and Service code between WP7, WindowsRT, MonoTouch and Mono for Android.

This was achieved using solutions where every project platform had:
  • a platform specific UI project containing code unique to that platform (e.g. UI widgets and views)
  • a platform specific class library which was exactly the same code across all projects – the only difference between the different platforms was a difference in the project library/build type.
For example, see the TwitterSearch hierarchy:




This type of solution works really well as a cross platform development architecture - it encourages code reuse, its easy to work in and it delivers product :)

However, there are a few things that I feel could be done better:
  1. Maintaining the different projects requires manual cut and paste maintenance which is tedious and error prone. There is a tool that can help with this – the Project Linker Synchronization Tool - http://msdn.microsoft.com/en-us/library/ff921108(v=PandP.20).aspx – but it only helps a bit…
  2. While the tools from Microsoft and Xamarin were first class, and while plugins like VSMonoTouch and VSMono help fill some gaps, there are still issues with refactoring. Fundamentally the above code architecture forces the project hierarchies to be independent, and this means it is impossible to do automated refactoring across all the hierarchies – and I find automated refactoring a very important tool for development.
  3. Because there are separate project hierarchies and separate build projects, it encourages developers to add non-portable code and to add things like ”#define”
  4. I expect this architecture will become less maintainable when I try to add Silverlight, WPF, WP8, MonoMac and PlayStationStudio to the MvvmCross platform. 

These portability ideas and questions are of course not new – they have been highlighted and discussed before by many other developers, including lots of notable “big fish” in the cross platform development community:

My personal hope for vNext for me is that MvvmCross will be able to achieve portability using the next generation of Portable Class Libraries.

What is a Portable Class Library?

The Portable Class Library tools provide:
  • a special class library project type
  • a set of portability profile definitions – each of which defines an “API level” which libraries must conform to in order for them to be portable. 
When a portable library project is built, then it builds against a given profile, but it only when the code is linked that the platform specific implementations of those APIs are actually located.

To understand PCLs more, Jeremy Likeness did a great 3 part blog post – see http://csharperimage.jeremylikness.com/2012/03/understanding-portable-library-by.html

What’s needed in PCLs for MvvmCross?


The profile I’ve been using in MvvmCross for my PCL work is “Profile 104”

This profile includes:

  • mscorlib 
  • system.core.dll 
  • system.net.dll 
  • system.runtime.serialization.dll 
  • system.servicemodel.dll 
  • system.servicemodel.web.dll 
  • a very small part of system.windows.dll 
  • system.xml.dll 
  • system.xml.linq.dll 

Almost all of these are supported directly in the MonoTouch and MonoDroid platforms, although a very small amount of type redirection and substitution is needed for System.net.dll and system.windows.dll

This is achieved through using dedicated “shim” assemblies which simply redirect the Type load calls from (for example) System.Net.IPAddress in System.Net.dll to System.Net.IPAddress in Monodroid’s System.dll
You can see this redirection in action for MonoDroid in:
By using this profile 104, then I have managed to get the solution down to a much smaller size:

 

Moreover, within this solution above:
  • builds for all of WP7, Droid and Touch within VisualStudio 
  • allows automated refactoring 
  • has no manual cut and paste steps required 
  • the build executables run on WP7 and Droid straight from the VS2010 environment. 
  • Behind the scenes there is now a superb new MvvmCross library and plugin architecture which also uses PCLs – and this makes producing and extending MvvmCross much easier. 

So… what’s remaining to do?


There's one major challenge remaining:
  • I can’t yet get this project to build and run within MonoDevelop on the Mac – so I can’t deploy onto an iOS device. 
This is obviously quite a serious problem!

However, the good news is that the latest Beta versions of MonoDevelop do seem to contain some new support for PCL :)

Currently I’m still playing with this support but the initial result looks good – I can at least load the same VS2010 solution inside MonoDevelop - and the PCL projects and their references all look to be present and correct.

I’m currently investigating some problems with incompatibilities between some core System.Core definitions – especially around System.Action and System.Func - and I do still have to find a way to get System.Windows.dll (touch) and System.Net.dll (touch) into the MonoTouch GAC.

However, this feels really close now…. The future is close… and it’s already looking awesome :)

5 comments:

  1. Hi Stuart, thank you for the post and the future does indeed look awesome! I'm still reading through Jeremy's blog posts, but did you need to do any tricks to get the MonoTouch library building? I'd love to see a follow up blog post with steps to set this up focusing on MT and MfA.

    Also, have you had any word from Xamarin about MonoDevelop supporting this approach?

    ReplyDelete
  2. I've had really positive feedback from Xamarin MonoDroid and Microsoft BCL team members - they've both posted me emails and blog posts helping me along the way.

    So I think this will be the way forwards :)

    I've blogged about my setup at http://slodge.blogspot.co.uk/2012/04/using-portable-library-tools-for.html

    Right now I've got everything building well inside VS2010 - including VSMonoTouch for ios.

    However, I'm still stuck with trying to get the MonoTouch/MonoDevelop code building properly on a Mac - and this progress is slow. From what Xamarin have posted I think they are expecting to make a lot of new changes and additions as soon as VS11 goes live, but I think they don't want to release much before then because if they release a beta to match Microsoft's beta, then there will be a lot of pain and confusion caused. Note - this is my "feeling" - not a statement of fact :)

    And when is VS11 ready? Maybe 3 months, maybe less?

    ReplyDelete
  3. hi,
    after getting an order for an Android program yesterday i stumbled across your MvvmCross library.
    It's awsome.

    But now that VS.NET 2012 is released, is there any progress in the portable class library support on MvvmCross side?

    ReplyDelete
  4. Thanks fzelle. The vnext branch works for droid and wp7, but I've still gotten nowhere on monotouch - there's an open bug request with xamarin, and they've listed 7 things needed for support - but there's no timeline on those 7 things :/

    ReplyDelete
  5. Thank you, didn't see that vnext branch in git.

    Atm i would only be interestest in Droid, WP7 and WinRT (in that order).

    Keep up the good work.

    ReplyDelete