Thanks to everyone who's been playing with Hot Tuna as it's gone through some pretty hefty Alpha changes!
The good news is that today MvvmCross v3 is now officially in Beta.
This means that the API is now 'locked off' - I will try not to make any more structural changes (e.g. renaming key Mvvm classes or moving them between namespaces) - indeed I'm hoping I won't make (m)any more changes at all...
This means you can now start to code against v3 safe in the knowledge that you are coding against a 'near final' version :)
There may still be additions made to Hot Tuna - there are a few open issues still to resolve - but overall it's stable now - and I love it :) :) :)
...
To celebrate, I've spent most of the last 24 hours playing with Nuget packages. You can see them on the nuget prerelease channel:
Make sure you are looking at pre-release packages inside Nuget - these packages will not show up in 'stable only'
Here's a quick (and rather rough) video of these packages at work:
I can't shout loudly enough about how ecstatic I am to have nuget working like this with Xamarin.Android. Mr Daniel Plaisted put in heaps of effort to make this happen... he logged hours on Xmas day last year through to Good Friday yesterday.
This is the Biggest Hottest Fishiest badge of awesomeness ever - @dsplaisted you are officially awesome 3 times over! Thank you Daniel!
This week, I gave my first Hot Tuna talk at Modern Jago in London
In all honesty, it was a warm up talk for Evolve and I was a bit ropey - sorry guys, I'd been so busy coding for the release that I'd left preparing for the talk until too late....
However, fortunately I survived - and I think all the fab Windows Store developers understood most of my message :)
And one of them....
Well, one of them was Lee Oades a dev who describes himself:
Pro C# Developer, photographer, guitar player, poker player and proud
husband & father of two
... I think this means two children, not two wives ;)
And yesterday, he followed up with the most fabulously detailed set of notes about where the talk was bad, bits that worked, bits that could have been better, how his dev friend had seen it and generally what would make it even more awesome. Beyond the summary text there were 18 (18!) really good points to look to improve
This is fabulous... totally fabulous... it gives me I can get on with preparing for Evolve - where MvvmCross will be at it's Hottest and most Tuna-esque
Lee, thank you - 100% awesome - grab an awesomeness badge and take a bow:
Also... very much looking forwards to seeing Lee talk in the future - the return favour will be my pleasure ;)
Last weekend, I got a tweet... just a few characters from Johan Otto - also known as: @MorbidCamel
How about a custom attribute for views like
[ViewModel(typeof(MyMvxViewModel))]alternative to naming convention
reflection in Setup
This was a Tweet that HotTuna really needed....
This sort of thing has been discussed before... and I knew it was there... but recently I'd been spending so much time just GettingThingsWorking(TM) that I'd missed the obvious...
So I'm delighted to say that now in MvvmCross v3 if you have a ViewModel like:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Then you can simply declare a view for it like any of:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Really this is awesome - totally awesome - I've now switched all my apps to this - it is just so obviously good - it's lovely.
Not only that... but this Tweet served as a reminder for MvvmCross back to one its roots - back to CoC - Convention over Configuration - something that we've been trying to do since v0.
Thank you @MorbidCamel - you helped make the #HotTuna even Hotter.
100% Awesome - this badge is for a Conventional-not-Configured hero called Johan Otto:
Not everyone agreed with the post - a few notable names said it was an already solved problem - that, code snippets, for example negated the need for this.
This class allows you to write and expose your ICommands as methods.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
After you've done this, then the commands can be accessed in XAML or AXML using markup like:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This approach won't be to everyone's tastes - but I love it - it gives users the choice to just name methods ending with 'Command' and these will automatically translate to ICommand's
Behind the scene's there's also more going on too - e.g. you can use parameterised commands, and you can use CanExecuteCommandName properties to enable/disable the Commands too. I will try to explain that more fully another day...
For now... @xamldude this was an awesome post - there's only one way to say 'thank you' - with a badge of Hot Tuna MvvmCross awesomeness:
Just following up from the post this week about the first of the v3 documents...
As well as publishing on the GitHub wiki - https://github.com/slodge/MvvmCross/wiki/_pages - the lovely people at CodeProject have also published the TipCalc sample.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Coming next will be the WindowsPhone and WinRT UIs - which I probably will cover in less detail.
After this first tutorial is done I'll start on other samples and walk-throughs, moving on from the intro and covering more advanced topics....
You'll notice I'm currently not saying too much about where to get
files from or how to setup the IDEs for PCLs... this is partly because
this area is changing a lot right now - so I think the docs could be out of date every week if I try to explain too much.
These are taking a lot of time to produce...
Are they worth it?
Is there something else you'd prefer to see instead?
MvvmCross is opinionated. It cares about how you write your code. Its opinions are:
Portability – you should use Portable Class Libraries for as much of your code as you possibly can - viewmodel, model, service and even view. Friends don’t let friends copy and paste. # is for twitter, not for code.
Interface Driven Development – you should use Dependency Injection, Inversion of Control and Plugins to get your applications richly and robustly to market on all of your target platforms.
Code for Test – you should use interfaces; you should develop small, cohesive, loosely coupled components; and you should add unit tests to allow your code to be used, reshaped and reused again and again.
Mvvm – you should use architectural patterns - especially Model-View-ViewModel with Data-Binding - in order to provide a structure within your app, and in order to deliver both a delightful application and a sustainable, flexible ongoing development process.
Native UIs – users love Native, and you should give them Native UIs that delight, that provide rich functionality and that are styled to fit naturally in the context of your users’ devices.
Your opinions matter – you should be able to override any part of MvvmCross, including it’s opinions.
The app is King – more than anything else, what matters is that you ship. Delivering is everything. The app is King.
A video from TechDays Belgium has been published today - and in it Gitte Titter provides just about the perfect introduction to cross platform Mvvm for existing Windows Mvvm developers.
And all of this in front of a huge and particularly rough looking audience...
@jonkeda,
Matthijs van der Veer, and
Jermaine Jong have together been building TeaLight - a huge and hugely impressive code generation framework for Business applications on top of Mvvm.
Featuring multi-platform support, local-remote data-synchronisation, customisable UI generation and automated testing, this framework builds on top of T4 templates and provides app generation direct from business definitions.
They presented this framework to an audience of over 80 at TechDays NL at the start of March, and are currently looking forwards to extending it to support Async, Nuget and more. If anyone else is interested and wants to get involved, then check out their wiki as the project builds and evolves on http://tealight.wikia.com/
For a really cool project, for beating brutal deadlines, and for truely delivering on the developers rule that real developers automate, I'm delighted to send out the first Netherlander Badge Van Awesomeness. Excellent stuff:
SeeD-Seifer also known as Alexey has been in touch a few times over the last few months - including helping out with a few bugs and issues, especially around Dialog functionality.
I've now just found out that he and the team at ArtOfBytes have recently shipped ALM2GO - a super clean looking project tracking tool for iPhone.
For shipping such a great MvvmCross/Dialog app, and for long-term services to Dialog, I'm really, really pleased to award Alexey a Badge Of Awesomeness!
It's great to see slick, delightful, robust business apps shipping on top of MvvmCross - awesome work by all in Hamburg and the Ukraine!
One of the goals of MvvmCross v3, Hot Tuna, is to allow other Mvvm and non-Mvvm libraries to take advantage of MvvmCross Plugins and MvvmCross Data-Binding without the developers having to buy into the entire MvvmCross experience.
For reasons I can't quite remember, this part of the project got the codename Chimp.
some simple AXML with some Swiss MvxBind statements inside
Importantly, this demo has references to only:
the very smallest core parts of MvvmCross - the CoreCross library
the MvvmCross.Binding libraries
On top of these references, I've added just a small amount of Setup infrastructure for starting IoC, Trace, etc, and this then allows the binding code to work for our simple View and ViewModel
---
To get to this stage has required turning MvvmCross completely upside-down in terms of dependencies... but I'm excited that we've now reached this result.
I'll try to add another demo or two in the next couple of days - but really... this is now an invitation to others - does anyone want to see if the Chimp will walk with their favorite Mvvm platform?
- A fragment declared in AXML and it's DataContext (ViewModel) set in Code Behind
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- Fragment switched in/out of a ViewGroup container programmatically using Code Behind
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
There's still plenty more to learn and explore in these Fragments - the lifecycle of fragments really is a bit odd... so this code isn't really fully production ready yet...
There's also quite a few other things to try - like maps, view pagers and bound fragment collections...
But at least fragments can now be used and can be easily data-bound :)
If you're making an HTTP Post on WP7/WP8 and you get back an annoying NotSupportedException, then one thing i might be is that you forgot to Flush/Close/Dispose the Request stream.
i.e. make sure that you do the `using` part of:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
One of the changes coming in MvvmCross v3 - Hot Tuna - is that the default ViewModel location and construction has been overhauled to provide 3 new features:
constructor based Dependency Injection
navigation using Typed navigation classes
saving and reloading VM state for 'tombstoning'
I'm sorry that these changes are breaking changes for existing v1 and vNext apps.
However, I hope we'll all find these changes very useful in the future.
How ViewModels are Created in v3
The default ViewModelLocator in v3 builds new ViewModel instances using a 4-step process - CIRS:
Construction- using IoC for Dependency Injection
Init() - initialisation of navigation parameters
ReloadState() - rehydration after tombstoning
Start() - called when initialisation and rehydration are complete
Construction
As in vNext, you navigate to a ViewModel using arguments like:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
In vNext, these navigation parameters were passed to the constructor of the ViewModel.
However, in v3, these navigation parameters are instead passed to the Init() method, and the constructor is now free to be used for Dependency Injection.
This means that, for example, a DetailViewModel constructor might now look like:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This Dependency Injection is, of course, optional - you code can instead continue to use ServiceLocation if you prefer:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Now that the construction is used for Dependency Injection, the navigation parameters move to a new method - Init()
Init() will always be called after construction and before ReloadState() and Start()
Init() can come in several flavors:.
individual simply-Typed parameters
a single Typed parameter object with simply-Typed properties
as InitFromBundle() with an IMvxBundle parameter - this last flavor is always supported via the IMvxViewModel interface.
You can declare zero or more of each of these types, but generally you will probably only want to use one within your application
So, for example, to support the navigation:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Note that multiple calls can be used together if required. This allows for some separation of logic in your code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
If the View/ViewModel is recovering from a Tombstoned state, then ReloadState will be called with the data needed for rehydration.
If there is no saved state then no ReloadState() methods will be called.
Exactly as with Init(), ReloadState can be called in several different ways.
individual simply-Typed parameters
a single Typed parameter object with simply-Typed properties
as ReloadStateFromBundle() using an IMvxBundle parameter - this last flavor is always supported via the IMvxViewModel interface.
Normally, I'd expect this to be called as:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
One of the new ViewModel APIs available in Hot Tuna is a SaveState pattern.
This can be implemented in one of two ways:
- using one or more paremeterless methods that return Typed state objects
- using the override SavedStateToBundle(IMvxBundle bundle)
Using a Typed state object:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
After all of Construction, Init, and ReloadState is complete, then the Start() method will be called.
This method is simply:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
For a real app, I would expect the navigation, construction and state saving/loading code to actually look like:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oh yuk - I hate it - this CIRS stuff is not for me....
If you don't like this CIRS flowfor building your ViewModels, then the good news is that you can easily override the ViewModelLocator within v3, just as you could within vNext :)
You can easily go back to vNext style ViewModel construction - or you can easily invent something new.
Oh yes - I love it - when can I use it?
Soon... very soon ...
... well, just as soon as I work out some of this MonoTouch->Xamarin.iOS pain :/
Most of the progress continues to be over weekends - but I'm planning on investing some serious time on v3 during March.
The current v3 status is still very much Alpha - names, namespaces, apis, and functionality may all still change - so I don't recommend using v3 unless (like me) you like pain.
But if you do try to use v3, then I'd love to hear from you ;)
Some more advice for intrepid adventurers who want to fish for some Hot Tuna:
As with previous versions, the best documentation today is the samples - but I am looking to change this.
There are a large number of changes from master and vNext - especially when it comes to namespaces and class names. I will try to explain this more in blog posts during March.
There are some big structural changes in v3 - especially the introduction of CoreCross, and the reversal of dependencies between MvvmCross and the Data-Binding code. I will try to explain this more in blog posts during March.
If porting code from vNext to v3, then there are some tedious changes to make. I will try to explain these more in blog posts during March:
Views to change from generic to non-generic
Namespaces to move
Project references to change
IoC to switch over to the new syntax
Problems with Xamarin2.0 to overcome
... and more besides!
If you would like an insight into v3, then I've prepared this slide deck as an introduction:
I'm still loving MvvmCross and cross-platform C# development - the future is bright, databound, and portable :)