NoApple

I’m sorry if I don’t share the wild enthusiasm about the broad direction Windows 8 is taking – as far as I can see, Windows is increasingly being reimagined in iPad’s shadow, and I believe Microsoft is explicitly or implicitly doing so at the expense and minimisation of the traditional desktop experience. Eventually, I think this ongoing narrow super-optimization of Windows will be pushed down onto all end-users no matter their use-scenario and that’s going to hurt us all.

iPad/iOS Reimagined

Let’s first establish just how similar is Windows 8’s reimagining to that of iPad/iOS combo:

  iPad / iOS Win 8
Facts    
Apps run in full-screen / chrome-less mode Tick Tick
All apps are installed, versioned, and stored independently Tick Tick
One has to source apps from a single curated App Store (* for the most part) Tick* Tick*
The OS is exposed using native libraries – Cocoa Touch Frameworks, WinRT Tick Tick
Apps are not compatible or enabled in the traditional desktop environment Tick Tick
All apps are isolated, and don’t share direct access to each other Tick Tick
Plugin-free Browsers (to protect the App Store model) Tick Tick
OS and Apps are Touch-Centric / Touch-First experience Tick Tick
Two broad-modes available for developing apps – Native and HTML Tick Tick
Provide/allow abstractions to enable multi-language use – .NET, MonoTouch etc. Tick Tick
Desktop Environment for Traditional Applications (* only the x86 platform will feature backward compatibility)   Tick*
Opinions    
The general drift is towards building tightly controlled / closed systems Tick Tick
There is a systematic effort to enable a generational vendor-lock in Tick Tick
First-party apps/services favoured above similar third-party apps/services Tick Tick

Obviously, there are small/big implementation, technical, and user-experience differences between the two – and to be fair Windows 8 is offering the traditional desktop environment in addition to the touch-first environment. That is the big/critical differentiator between the two; one Microsoft is obviously hoping will give them a catapulting strategic-advantage over Apple. Now, I absolutely don’t fault Microsoft in going after this market, iPad and broadly touch-first experience is an existential threat to Windows and Microsoft’s overall dominance. However, I feel Windows 8 tilts the balance too far; in that it is doing so at the extreme expense, almost neglect, of traditional desktop applications – the same one that has been its bread-and-butter for ages.

Touch-First Experience Realized : An example

With the understanding that Windows 8 is still not even a beta product, and things will most definitely change – have a look at what is involved in putting the computer to hibernate using a mouse based approach:

Step2 Step3
Step4 Step5

Now, to my counting that’s like 7 explicit steps involving three clicks, three separate menus/panels, and requires moving to two extreme ends of the screen. Just to go through the motions – step 1 involves moving to one specific corner of the screen, step 2, wait for the menu to slide-in and then move to the settings menu item, step 3, click on the settings menu, step 4, wait for the slide-in settings panel and then move to the power menu button, step 5, click on the power menu, step 6, wait for the popup menu and then move onto the hibernate option, and finally step 7, click on the hibernate option.

AllSteps

Contrast this with one, the fact that most mobile/tablets are not often shut-down and, two, most of them feature a hardware button that puts the device to sleep – which in some respects rationalizes the logical and spatial layout of the power-down functions. However, mouse based devices are left with the short end of the stick.

Worse still, to my knowledge, there are no keyboard steps that allow you to power down a Windows 8 machine – the other day, my Bluetooth mouse went south and I couldn’t get to the power option. Good thing, I knew the command line argument to restart a computer; but still that points to the fact Windows is being optimized away from the mouse-keyboard combo.

Downgrading the Desktop Experience

It’s not just about the UI, which admittedly is still in flux, but everything from exclusivity of Metro design language within the new immersive experience, exclusivity of the new Windows RunTime (WinRT) again to the immersive experience, and the cosmetic improvements to the traditional desktop side (wohhoo, explorer with ribbon) speaks to the implicit downgrading of the desktop experience. If bullshit walks and money talks – then follow where all the resources are being put into.

You can’t re-imagine windows and leave the desktop experience behind – even though there is a ton of legacy burden to carry forward. For example, the Metro design-language, could equally be applied to the desktop applications, but how many Metro-style desktop applications did we get to see? Rather than Microsoft leading with tools, controls, and examples the enthusiasts’ community is showing us what’s possible:

Live Mail Concept (By Clindhartsen) 
MetroMail1 
Windows 7 Cued Twitter Desktop App

Further, Microsoft holding off the entire WinRT platform from desktop-applications is a crying shame; especially in light of its infamous proclamation of “our strategy has shifted”. So after the big reveal at Build, what new options do desktop applications gets – well, none new, just more of the same, .NET, Silverlight, and the usual native stacks. There might be some technical reasons not to support desktop applications, but my guess is it’s mostly political or business for that matter. So it seems, after all these years and lots of playing-coy, Microsoft’s desktop UI strategy will remain in the same mess/disrepair it was pre the Build event – @##%!

Perspective

Couple of months ago Steve Ballmer was belittling the size of the tablet market v/s the PC market size – 20m v/s 350m units (as of last year). And yet, here we are couple of months down the line, and Microsoft is putting the tablet experience at the heart of its flagship. So what just happened? Putting in the tablet experience is not the problem; it’s the relative demotion of everyone else that needs some perspective.

I fully understand and appreciate the value of tablets (personally, I’ve even been accused of evangelizing them), but it has its specific place/use vis-a-vie the traditional desktops – even as we get touch screens the big 20+ inch monitors are here to stay too, especially in the production environment. The so-defined “metro apps” seem out-of-place and forced to me when used in full-screen only mode – in this respect, I think Apple (again) got it correct in Lion, their full-screen mode works relatively seamlessly when paired with a trackpad and also goes around their traditional window-management weakness(es). The critical differences in Apple’s approach being, for one it is optional, second it is designed for pointer based applications, and lastly it feels additive (not exclusive) as with just a simple swipe you can escape the immersive embrace, as it were.

MixTab Full Screen App

Similar perspective is needed on WinRT – I personally think it’s a validation of Silverlight and .NET’s model. Apart from the managed environment needs, WinRT follows a similar packaging-model, metadata-model, access-semantics, asynchrony approach, designer-developer’s separation approach, multi-lingual model etc. laid down by both Silverlight and .NET. Further, WinRT is being sold as native-native to Windows, well, to me both SL and .NET could/should also have been such native-native platforms; the difference was basically that they were not as good/deep as an implementation as WinRT, they perhaps tilted too heavily on the productivity side, and had multi-platform support constraints that created too high of an abstraction with perf implications. And unfortunately too, Microsoft didn’t have the appetite to fix the issues – so they ran for a greenfield approach. However, given that WinRT comes from the Windows’ team and they seem to be tied to a 3 years cadence, whereas iOS, Mac OS X, and Android all sticking to around a year’s release cycle – will Windows / WinRT be able to keep up? I donno.

I See Green

Windows8Green

Credit where credit is due; Microsoft deserves some huge kudos for the big and bold steps they are taking, and even more so for the technical improvements they are bringing to bear at the OS level. Moreover, on the tablet front, after years of struggling they now seemingly have a technically competent platform, plus they and offering improvements beyond the markers already laid down by Apple – that will make them competitive, but then again they are adopting the good with the bad! And, in the big picture, especially when you consider they are betting (and/or exploiting) their biggest strategic assets (Windows) they should be more mindful of carrying the entire ecosystem forward not just a particular segment. I think they are swaying way too heavily to counter iPad, leaving behind their hereto market of desktop applications. That’s a folly and I think it will come back and bite them, just as letting the smartphone market to auto-pilot did; today though, a lot of Microsoft’s decisions makes sense from a specific prism, but that prism is tinted green in Apple’s envy.

Apple

Posted by Rishi on 20-Sep-11 1:22 AM, 95 Comments

Categories: General, Technology, Other, Opinion

Let me start by saying that I love Windows Phone 7 (wp7); it’s a modern, well-throughout, and refreshing OS. However, in as many good things there are about it, and there are many, it suffers from a metaphorical “death by a thousand cuts”. Nonetheless, I think all the issues are correctable by either technical or strategy changes, and looking from a developers perspective the following ten suggestions (in particular order) could change the game for Microsoft in so far as being able to match the best-of-the-best:

1. UI Virtualization

As everyone knows, most of the time within the screen confines, we are privy to only a part of total viewable UI – and so the idea with UI virtualization is that we only have to realize visuals for the view-elements that are (at the time) viewable on the screen. It’s not a new concept by any means, but it’s a critical piece of technology for a limited resource device – and the problem is that Silverlight’s support for UI virtualization is very anaemic. For example, out-of-the box we don’t get UI virtualization support for things like wrap-panels, pivot/panoramic panels, elements with non-similar heights, grouped items etc.

VirtualizeLike above, the potential field of view is one panel to the left and one to the right, everything else could be (optionally) virtualized. Furthermore, one of the other related issues is scrolling, either because of lack of UI virtualization or container recycling performance – which let’s be honest is a prevalent usability failing on wp7 apps. So what I’d like to see is that we get across-the-broad and optimized UI virtualization support for wp7 out of the box. And, this is critical because for one thing, resources are limited on phones, and virtualization-performance or even the lack-of-virtualization issues are particularly perceptible with touch-based input.

2. Hardware Acceleration

The other big ticket item that must be addressed is that Silverlight’s rendering should be done on the GPU, and not on the CPU – and unlike the desktop version, where the excuse that user might not have some sort for compatible hardware is null and void on wp7, as it only runs on a well-known hardware. The potential performance gains from hardware acceleration are in such order of magnitude that this shouldn’t even be debatable, even though technically it might not be the simplest thing in the world to achieve.

In terms of the benefits, having the rendering done on the GPU will speed up other things like networking, data-processing etc. because as of now the CPU is being overtaxed; furthermore, it will also improve the memory footprint, and even help with extending the batter life. All big wins in my book.

3. Improve Navigation and Navigation State Management

Navigation is a topic close to my heart, and I’m not particularly happy with the way navigation is done on wp7. For one thing the navigation model must be truly asynchronous, to have the ability to cancel, confirm, delay etc. And the current recommended approach to delay passing the event argument to the base class is one the weirdest view-related pattern I’ve ever seen. And the other thing is it’s not MVVM friendly, because most of the logical reasons as to proceed or cancel with navigation should be taken in the ViewModel.

Further, the hydration and de-hydration of the visual tree as a tool to manage the navigation state is simply spurious. It’s actually quite similar to the much-hated ViewState model in asp.net, and consequently I think it’s wasteful, it has a significant memory footprint, and just hits performance. The right navigation state model should do two things, one, only store the visual-cues that matter to the experience at hand and this has to be determined by the developer, and second, it should allow storing of the logical state which in my books means it should be MVVM friendly. If done correctly, it would both improve performance and reduce the memory footprint, because remember navigation is just another form of UI Virtualization.

4. Fix Push Notifications

In wp7 push notifications are serious broken, especially from a usability perspective. For example, the channel identifiers required for sending notifications are temporary, because they get reset every time the device is restarted (which because of how the marketplace app locks-up is almost a daily exercise for me). This is such an unintuitive and unexpected behaviour, that it defies any privacy arguments for resetting the identifiers – especially for people coming off iOS. Then there is the issue of capping the number of apps that one can receive notifications from (16 I believe) – again this is a usability disaster; because it is counter-intuitive (again as compared to iOS), it’s an arbitrary limit which I don’t understand the reasons for, and also just because a user has no central place to either know or manage such subscriptions.

In terms of improvements, I think we could have the idea of public and private notifications channels – such that if one is subscribe to a public channel then notification goes to all those who’ve subscribed to that channel (in a broadcasting kind of way). And private channels would be the ones that target a particular user. And I think, with a little bit of thought, Microsoft can extend the notification infrastructure to allow intra-application communication – this is something that, if done well, can bring to bear a lot of interesting apps mash-ups.

5. Design for Extensibility

I’ve already done a rant on this, but in many other ways there is still a case to be made that because wp7 is a managed platform the onus is on Microsoft to provide infrastructural capabilities for apps to built-upon. Now the problem lies with the fact that you have to wait on the underlying platform to be updated as a whole, to a gain a new capability. That I think is a fundamentally flawed approach, especially keeping in mind how fast the market and hardware capabilities are moving – so how about, if we could have independent trusted/certified dlls, that could be added to the xap and used to consume additive capability in isolation – like say NFC capabilities that might be introduced by one set of phones.

Essentially, what I’m talking about is embedding interops that are smart-enough to test if the capability can be availed on the device, and if true then wp7 gets the necessary installers and install it from Microsoft directly (into maybe something like a GAC). So lets take an example of sockets capability – in such a setup, Microsoft can in isolation make an interop available and apps can avail them before they are introduced into the platform as a whole itself – and just to note, once the capability has been subsumed in the underlying platform then Microsoft could just disallow any app from including the interop. With something like this the time-to-market can be significantly cut-down because you can test and add capabilities in a piece-meal fashion. And the benefit being wp7 as a platform can potentially be on the cutting-edge of hardware/services – without the negatives of dll hell or the delays with moving the platform as a whole.

TaskSwitcher6. Introduce Pseudo Multitasking using Tomb-stoning

Multi-tasking, or pseudo multi-tasking (or apple’ish multi-tasking), has two facets – one the ability to do certain tasks in the background (like play music) and two, resume from where you left. The second facet is essentially what we call tomb-stoning in wp7, so how about availing the state whenever an app starts – why should it be only restricted when accessed by navigating back. This is so easy to avail that I was surprised it wasn’t in the box, because we already have the application-side of the infrastructure in place. So the only thing that is really needed is a task-switcher kind of UI (as shown on the right), which again taking cues from iPhone, could be triggered by double-clicking the home button. The running apps tiles too could be made “live”.

And with respect to the other capability of having certain tasks execute in the background is again not difficult, all that is needed is to provision “named” background threads that can only do non-visual tasks. And in Silverlight we already have a background-worker approach, and we could foreseeably use something very similar to that – with the main idea being you have a qualified interface that does dispatching back-and-forth. Technically, I don’t think it’s a big challenge – especially because apple has put in the though-process already in so far as the types of background tasks we need.

7. Improve the Home Screen

Tiles are an excellent idea, but the current implementation of the home-screen comes at the expense of application discovery and limited usability. In as much as Microsoft parades the grid’ish approach to apps listing, the one thing they do provide, in terms usability, are big bold graphical hit-targets that are conducive to developing muscle memory. However, in wp7 because live tiles and apps listing require heavy scrolling and in the other case we have text-oriented targets, the muscle memory ability is severely diminished, and consequently it takes longer and requires more metal involvement to get to any app. And I can feel that extra effort’s pinch when I compare it to my experience on my iPad, not exactly fair but still, where I’ve put everything into folders in just one screen and it doesn’t take me more than two touches to get to any app; plus you also get the speed because of the muscle memory you’ve developed over time.

MultiPanelHomeScreenWithout radically changing the home screen, I think one of the things that can really help is having multiple sets of live-tiles. I can imagine organizing various live-tile sets – one of people I contact often, one for games I play often, apps by category etc. Yes, it adds lateral scrolling/swiping but that not necessarily a bad thing, it’s same idea of an “infinite canvas” in play. Secondly, it’s so ironic that despite having a hardware search button you can’t search for your apps – that needs to be corrected, a press on search button should allow you to search for apps when on the home screen, period.

8. Update Back and Search Buttons Behaviour

I seriously think Microsoft got the back button and search button functionality somewhat wrong. I think the back-button should only navigate within the context of an app. Hoping apps by walking up the back-stack is counter-intuitive, it might work for task-like application hops, but it’s just not right in terms of app-to-app usability. So my suggestion is this, one, let the back-button only work within the boundaries of an app (i.e. it shouldn’t cause one to exit an app – when was the last time your browser kicked you out when you backed-up? or where is the forward button to recover from an accidental exit?), and second, introduce a long-press on the back-button that takes you to the previous application (with tomb-stoning and all). Using the long-press, as opposed to backing up n-times, would also preserve the back-stack on the running application, and that is sometimes important with things like the browser (plus we won’t end-up backing up over POST actions, which is bad bad bad!).

Similar to the back button, the search button should be contextual to the app running – and in cases where the application doesn’t handle it, it should do nothing. This behaviour would be consistent with the use of the search button in native apps, plus it would also allow its use within the home screen. Now as for accessing Bing, introduce a long-press on the search-button to get to Bing – like the back button, this would consistently hop the app-boundary and also maintain the availability of Bing from basically anywhere in the phone. And for those like me with fat fingers, we won’t constantly be jumping out games and apps because of unintended hits.

9. Introduce Built-in SkyDrive API for Apps

One of the big visions of the mobile era is that of apps that fully “live in the cloud” – we’re somewhat there in an ad-hoc and patchy kind of manner, but not quite there in a truer sense of a platform. This is a vision that wp7 can take the mantle for, since Microsoft already has a lot of the technology and assets in place – namely, the 25GB provided through Sky-Drive and Live Mesh / Live Sync technology.  Imagine, having a cloud version of IsolatedStorage that could be shared across devices and Microsoft platforms – I reckon it would have a profound impact on how app’s user experiences flow across platforms and devices.

10. Introduce a Companion WP7 based Tablet

Of all the points here, nothing riles me the more than Microsoft’s inane tablet strategy, it’s like they just can’t grasp the failing of windows mobile – and the consequent ceding of billions-of-dollars worth of market to Apple and Google. What was the single biggest problem with windows mobile? Not features, not app count, rather it simply wasn’t designed for a touch device and it just didn’t work from a touch UX perspective. Now, contrast iPad with a Windows 7 tablet device – was Win7 primarily designed for a touch device? No. Does it work well from a touch UX perspective? No. It’s history repeating itself, Microsoft is ceding time and market to both Apple and Google again – and this is all despite, again like with smartphones, having a unique heritage in the tablet form-factor. Insane!

The Windows 8 System-on-a-Chip (SoC) is a laudable goal, if you can unify multiple form-factors – wonderful, it’s what sci-fi looked liked couple of years back. But, this strategy has got two problems, by the end of 2012 you will be three years out from the introduction of the iPad (ahem, just like 3+ years from iPhone to wp7’s introduction), and two, you could potentially hit a fundamental/technical issue(s) that could make it less than an idea solution (maybe like jack-of-all-trades but master-of-none) because really it is a such a challenging undertaking (Longhorn anyone? Pesky little history again). So why not take a path that has proven to be successful, take your phone OS and scale it up. And I believe, Silverlight, because of it’s awesome layout sub-system and MVVM type separation capabilities, would make for a wonderful application platform for tablets. And this can be achieved rather so quickly and cheaply (ironically on the back of Android tablets coming out now), that conceivably devices can be made available in time for holidays.

Lastly, from a developer’s perspective – iOS and Android developers get a one-for-two deal, in that they can at the same time make apps for two platforms. That’s twice the monetization opportunity with minimal effort – yet, don’t forget the fact some apps are just about only practical on a table-form factor which totally isn’t even an option for wp7 developers. That’s a handicap, that’s a loss-of-mindshare, and that makes the wp7 platform less attractive. These are just simple business 101 facts, and so it boggles my mind how does the biggest software company in the world miss the boat by such a large margin – and mind you this is not some iffy stuff, this has a profound and real effect on the long-term vitality of the windows eco-system.

Wrapup

Windows Phone 7 is a beautiful beautiful platform, there is no denying that – and that in itself is a big surprise because Microsoft has outthink everybody else in terms of the UX. However, in the current era of iPhone, Android, and iPad, this only takes them so far, it needs to be backed up a lot more substance, and a lot more functionality – neither is improbable, it’s just a matter of execution and strategy. And I just hope Microsoft can take input from the community and aggressively take the leaps required to make wp7 the platform of choice – and I like other developers will do our part.

Posted by Rishi on 11-Feb-11 7:05 PM, 49 Comments

Over the weekend I was working to make WP7 more useful as it were, but all I have is scars to prove that I fought with the platform. Here’s a mini-selection:

All your IApplicationBars Belong to Us

IApplicationBar
What's the point of having an IApplicationBar interface, when one must use one and only implementation provided in the box. Yes, I'm aware it's rendered “natively” and not by Silverlight, so I'm not even asking for a bindable version.

Become Hostages to PhoneApplicationFrame and PhoneApplicationPagePhoneFramePageThese two classes encapsulate the only way to get phone hardware/application specific notifications for three things, namely:

1. Orientation Changes
2. Back-Key Press
3. Obscuration Changes

And what I can't understand is why not treat these hardware/application notifications like say the Accelerometer or GPS or Push Notifications. That way you won't be tied to any specific use-case, unless of course Microsoft's pre-envisioning department had pre-envisioned all use-cases. Similarly, the only other things an PhoneApplicationPage provides is getting/setting ApplicationBar, Support Orientations, and State, all of which could be / should have been done using attached properties - the right way to bring in case specific functionality.

I Navigate NOT

So, well, you give in and make use of PhoneApplicationFrame and PhoneApplicationPage, and then you just happen to notice that you can change it's navigation behaviour since it implements INavigate interface.

INavigate Oh not so fast, if you provide your own implementation it just takes away all phone specific functionality, so for example ApplicationBars are rendered useless even though you have the entire infrastructure as required in place. Again what's the point of abstracting INavigate when you mandate the use of one and only self-anointed implementation.

On a related note, I'm not going to rage on the stupidity of having to respond to a Navigation request with an inline response, given Silverlight by design only supports non-blocking calls - so for example if you wanted to properly save something back to the  server before navigating away, good luck with holding the fort with Thread.Sleep(1000) loops.

What's that Gesture you are making?

Gestures

I don't know, but given the primacy of touch input in modern phones, you'd think gestures would be as natural to WP7 phones as say butter is to bread. Well, or at least Microsoft would like you to think so, they've got an entire namespace dedicated to gestures. Except they had the good sense to internalize it completely, so it's good enough for use by their two premier gesture-driven controls but not for direct use by developers. Wonderful.

Default Task > Root Visual

One of worst paradigm I've seen in WP7 is the idea of having a default task – the idea being SL will execute a specific task when the application starts, and in all cases (i.e. no extensibility) it would try and navigate to "MainPage.xaml" and if that doesn't take effect within 10 seconds it will kill your application. The definition of this task is nicely tucked away in the manifest file, with a warning to boot:Manifest I can see the broader need to ensure an application is responsive, but to me this technique is absurd as an app could easily come unstuck past the first navigation, which as I understand is also monitored for, so why double do it. Secondly, without locking one into a navigation-only approach, Silverlight's original set-once RootVisual model worked well - it at least gave you flexibility let alone the idea of extensibility.

Bigger Picture

To me some of these things show lack of critical thinking or worse a "I know best" mindset. Silverlight or broadly WP7's application model is as it is a highly constrained platform (just look at the "can I" questions on the WP7 forums), and chocking innovation/ideas other than the ones presented out of box is stupidity given the marketplace challenges WP7 faces. Obviously, I'm biased in my assessment, but for a comparison look at the approach MVC took in building their platform - almost everything is extensible or substitutable, and the reward, greater involvement and innovation through the community to the point where MVC 2 and the Razor View-Engine have been directly inspired by the work done by the community. Or then again we can just choose to live in the sandbox that Microsoft prepares.

Posted by Rishi on 26-Sep-10 8:14 AM, 19 Comments

Continuing with my efforts to showcase how to create end-to-end applications using nRoute, this time we have a Windows Phone 7 (WP7) based board game called Square Away. It is actually one game out of a multi-game application I’m creating for WP7, and is based on the “Bubble Breaker” theme. To create the game we’ll use the MVVM pattern, creating all the three triads and then use nRoute to bring together everything into one squarely game.

Squares

A word of caution, this is not a super optimized application and is clearly designed to showcase what nRoute has to offer rather than creating an end-user application.  More...

Posted by Rishi on 18-Jul-10 1:17 PM, 18 Comments

Couple of days ago I published a sample app in Silverlight that fronted Netflix’s oData API – well, now I’ve ported the same app into WPF again making use of nRoute Framework. It like before demonstrates how you can build an end-to-end application using nRoute’s navigation framework and MVVM related features-set on WPF. 
 nNetflix2
nNetflix1

As this is just a port, the preceding Silverlight based step-by-step guide is fully applicable here; besides templating and some implementation details the through-process is about equivalent – and so in this post I won't go through the nitty-gritty of designing the app, rather I’ll just discuss the broader ideas, issues I faced, and changes I had to make to up-port it to WPF. More...

Posted by Rishi on 11-Jul-10 11:48 AM, 22 Comments

With the latest release of nRoute we’ve added a trove of navigation-related features, to explain and demonstrate these features I’ve put together an end-to-end application that fronts the Netflix’s oData Catalog. And so in this post we’ll go through using these feature in a step-by-step manner to cumulatively compose a rich, extensible, and loosely-coupled application. Here is what we are going after:

PersonListing

MovieView View the nRoute’s Netflix App (note you can also install the application on your desktop).

Guide Scope

Right off the bat, let me be clear, this post does not show you how to consume oData services or explain how to design iPad’ish UIs or troll on the virtues of MVVM – it purely concentrates on plugging-in nRoute’s navigation and related features to compose our demo app. Familiarity with nRoute concepts is not a must, but will be much helpful. Secondly, just as I finalized this post, Netflix switched from a purely server-side paging-model to a hybrid client-server paging-model so I had to revisit the code, hence there might be a bit of mismatch from what’s shown here and the actual code.

Step 1. Application Setup

For our application we’ll split up the solution into two projects, one the main Silverlight (xap) application and the other a class library which will hold the Netflix service. And so first, in our data project we need to add a service reference to the Netfix oData Catalog.

CatalogService

We also need to need to add references to nRoute, so in both our Silverlight projects we add references to nRoute.Framework.dll, along with its dependencies System.Observable and System.Windows.Interactivity. And lastly you need to cross-reference the data project to the main application project. More...

Posted by Rishi on 30-Jun-10 1:21 AM, 42 Comments

I'm really excited to introduce the latest version of nRoute - this has been brewing with me for a long-time and I'm really happy about the feature-matrix that this release brings to bear. This release is a major one, for a couple of reasons - first, this release propels nRoute to three platforms, two, it takes big strides in making the underlying infrastructure asynchronous, three, it significantly updates the navigation infrastructure, and four, it brings extensible Dependency Injection (DI) into play which allows top-down composition to cascade through the application.

nRoute Overview

ApplicationFeatures

Now my intention with this post is to cover what's new and what's changed, but before that I want to just give an overview of nRoute. Basically, nRoute is a composite application framework that allows you to break and compose your application using various application-level constructs, as show in the diagram above. It is highly prescriptive in terms of its use of Navigation, IoC, DI, and other MVVM design patterns. It comes in two flavors, the full framework (nRoute.Framework.dll), and the toolkit version (nRoute.Toolkit.dll) which lacks the Routing Engine and the sub-features associated with it (shown in green above).

The Routing-Engine basically provides Url addressable content and actions - this helps you break your applications into smaller-chunks that can be brought together in a very loosely-coupled fashion - just like on the Web. The Messaging-Framework allows for loosely-coupled communication between one or more parties, without either having direct knowledge or keeping direct references between each other. Lastly, the Resource Locator Framework (RLF), which is an IoC component (and now a DI component too) allows for extensible and open-ended composition at runtime - build upon it are various features such as Modules, Services, View-Services, View-ViewModel support etc.

For more information on all of the above, check out some of my older posts, though do note that quite a bit has changed since:
Introducing nRoute: an application-flow framework for Silverlight and WPF
Introducing nRoute.Toolkit for Silverlight (Part I)
Introducing nRoute.Toolkit for Silverlight (Part II)

I'm looking into put together a single document that highlights nRoute's depth and breath, but for now these blogs posts will have to serve as scattered documentation.

Multi-Platform Support

SimpleMVVMWith this release we now have out-of-the-box support for Silverlight, Windows Phone 7 and WPF. This is a big branch-out from nRoute's Silverlight-only roots, but between the growing convergence of WPF and Silverlight and three independent WPF implementations of nRoute out in the wild, we've managed to bridge the gap. All the same, it is important to note that for the foreseeable future the center of gravity of nRoute, in terms of features and scope, will remain aligned with Silverlight despite the wider canvas afforded by WPF.

Asynchronous Routing and Navigation

First a little background, in nRoute we have two core interfaces that handle routing and navigation - the IRouteHandler interface essentially "sources" the response for an Url request (i.e. gets the content), and INavigationHandler handles the routing response (i.e. displays the content). These are like the two main cogs that make content sourcing and its visualization work, and with this release we tweaked both of them to make them work asynchronously. With respect to IRouteHandler, rather than just returning a response, we changed it to return an IObservable of the response - a seemingly small change, but it makes a fundamental difference:

IRouteHandler

Secondly, as it was, INavigationHandler separately processed the request and the response - which allowed us to be asynchronous in-between the two calls. But now with this release we've also tweaked INavigationHandler to respond to any navigation request asynchronously, by returning a yah/nah through a callback. It is also a little change, but has a profound effect:

INavigationHandler
With the new definition, we can now respond by consulting with the active View/ViewModel as to if we can proceed - and this is important as most of the can/should navigate reasons are contextual to the task at hand. In terms of the normal designer-developer workflow you don't need to deal-with the INavigationHandler or IRouteHandler directly - rather, as we'll see next, you deal with some predefined interfaces/contracts that optionally provide you control over how things like closing the current-view, navigating to a new view etc work. One common scenario where this really helps is when you want to navigate-away from a page, but before that you want to contextually consult the user about cancelling, saving changes, or continuing with the navigation - this gives your the entry point for that.

Formalizing Container-View/ViewModel Communication

One of the common problems with MVVM tuned applications is how do we communicate with the ViewModels from the outside/shell - well, the answer is simply, define a contract and use that as the basis for communicating. And with the new release we've put in place some mechanisms to make this extremely easy and extensible - I'll need to defer showcasing this to another post, as I want to explain it with an example. Making use of this technique, we've got three build in contracts that are used by various navigation controls to communicate with your View/ViewModel (which ever implements it). These contracts are refinements over what was available before, but they are much more well-strung now:

ISupport_thumb[2]ISupportNavigationState allows you to optionally participate in a container-maintained state management functionality (just as before, but the interface has changed). ISupportNavigationLifecycle (also changed, but like before) helps with lifecycle integration, by passing-in the parsed Url-based tokens along with the request's parameters, and as mentioned above it also allows you to participate in the closing of the active-view. A very simple way to exercise both the ISupportNavigationState and ISupportNavigationLifecycle interfaces is to use the new NavigationViewModel, which in addition to the two interfaces also implements INotifyPropertyChanged interface. Lastly, the ISupportNavigationFailure is used to visualize navigation error information, as we'll see ahead.

Globally Named Navigation Containers

Often you'll find that you want to trigger navigation in some container that is not directly accessible within the operating name-scope or even via the VisualTree - for such cases, we've introduced a simple mechanism to globally register a container with a string-based identifier, and then target the container for navigation using the same string identifier.

NavigationHandlerBehaviour 
To register any container globally use the NavigationHandlerBehavior and simply provide a name - as shown in the figure above. Now, internally we keep a weak-reference, and if another container registers with the same name then the last-one-in wins. Secondly, to target the globally-registered container specify the HandlerName (as shown above) on the any of the various navigation inducing behaviors (described ahead).

Application-Wide Default Container

In earlier versions to specify an application-wide default container, we had to hijack the Application class - well, no more - we specify the application's default container by just using the above mentioned NavigationHandlerBehavior and checking the IsDefaultHandler option. Also, in case of multiple opt-ins the last-one in wins, and to access the default container programmatically use the NavigationService static class. Note, when you want to use the application-wide default container you don't need to specify the navigation handler name.

Browser-Shell Integration

Browser-shell integration was earlier quite messy, now all you need to do is to drop the NavigationShellIntegrationBehaviour and you are done - clean and simple, and there are no options to fiddle around too.

NavigationShellBehaviour
This behavior makes use of the Silverlight's built-in Browser-History Manager, however it has the limitation of only being forward-only, which means you can't use it with navigation containers that allow directional navigation (like BrowsingNavigationContainer). For use with direction-aware containers I'll release an out-of-bound behavior, which will use of a different Browser-History Manager. Also, note this behavior is not available for WP7 or WPF, and when in Out Of Browser (OOB) mode it disarms itself.

Added StatefulBrowsingNavigationContainer

Unlike WPF/SL we have a flexible approach to containers (aka Frames) that display navigation results; in nRoute our approach is to offer different containers for different navigation use semantics - so some offer browser like state-management, some offer browsing history, while others just offer onwards-only navigation. Now, with this release we're adding a new navigation-container called "StatefulBrowsingNavigationContainer", it allows browser like back-forward navigation whilst allowing each page-type to share the same common state. Think about how in a Web-Browser each individual page in your navigation history keeps its own navigation state - well, with this container each page-type will have one common state whether they be in the forward or back stack or even if you just directly navigate to the page. So when you back up or go forward, the same single state will be returned - and I personally find this quite useful for desktop class application. This is actually an hybrid of StatefulNavigationContainer and BrowsingNavigationContainer.

Also as a related point, with this release we've update all the build-in container templates, they now match the Silverlight's standard way of templating content controls. Another changes is that the template now shows an overlay with an animated indicator whilst navigating (it uses a spinning indicator by Felix Corke).

Navigation Adapters

NavigationHandlers  
Implementing navigation containers in nRoute is really quite simple, all you really need is an INavigationHandler implementation - and there are two approaches to this, one is to make custom controls from the ground up, which we have (as shown in the hierarchy above) and the other approach is to tack this interface onto existing controls, which is relative easy. However, inheriting and extending controls is not exactly pleasant, and indeed in some cases it's not even viable - so as an alternative, with this release we've standardized a way to create so-called "navigation-adapters". These are essentially behaviors that implement INavigationHandler and can be drag-dropped onto any targeted control. And by the virtue of having the behavior all of nRoute's navigation infrastructure will seamlessly work around your targeted control. So for example, you want to handle navigation in a Tabs-Control, write a little behavior for it, drag-drop it, and you're done - no need for extending any control.

Now, because a lot of the functionality for adapters is common we've build in an adapter base class, obviously called NavigationAdapterBehaviorBase<T>. It only requires you to handle the displaying of content when navigated upon - and it's basically like visualizing the navigational content. Consider you could make a custom navigation adapter for a 3D panel, and each navigation adds to the 3D content. Additionally, we've also create an ItemsControl navigation adapter (numbingly called ItemsControlNavigationAdapterBehavior) that basically can append to an ItemsControl any navigated upon content. And because it's an ItemsControl, you can use this will all sorts of panels. This is a very powerful and flexible model and I'll have to showcase it separately, but the idea behind it was to allow you to create custom use-models, not just the linear navigation apps we are all used to. You can even create MDI type of application, and combine it with all benefits of a navigation-style app.

Abstracting Container Behaviors

One other new thing we've done is to abstract the common navigation-related functions such as refreshing, navigating back/forward, purging journals etc into well-understood interfaces; some of these are:

ISupportContainerThis helps, because now we can consistently target functionally-similar containers, and indeed we've build into nRoute the following behavior-actions to that take advantage of the abstracted commonalities:

NavigationBehaviours

NavigateActionSo like if you want to refresh a container, drag-drop the RefreshNavigationAction, point to the handler and you're done. Now, the most useful of these behaviors has to be the NavigateAction - which as it self-suggests induces navigation, and its use is shown in screenshot to the right. The Handler property is useful when you want to directly bind to an INavigationHandler object, but mostly you'll either just specify the HandlerName or actually not specify any handler (as we'll see ahead, why). Note, the Handler Name can either be an element name within the control name-scope, or it can be a globally-registered handler name (as we described earlier). The parameters collection allows you to pass-in a name-value collection with any navigation request, think of it as a Form/Request Collection in Web-Forms. We'll get to the SiteArea in a bit, and the Url is obviously the Url one wants to navigate too.

Now, I just wanted to point out the workflow of how we resolve the navigation-handler (this is slightly changed from before), we have a five-step approach, described below:

  1. If we have a navigation-handler directly specified/bound (Handler Property), then we use that
  2. If we have a handler-name specified, we check for an element with that name in our control name-scope; if found we use that
  3. If we have a handler-name specified, we check against the list of globally-registered handlers; if found we use that else throw an exception stating that the handler name was not found
  4. We look up in the visual-tree for an INavigationHandler, it can either be an control implementation or it can be via an attached adapter - we check for either; and if found we use that
  5. Lastly, we check if we have an application-wide container specified, if so, we use that - if not then, we return null and the handling logic would normally throw an exception stating handler not found

The interesting part is part 4, which basically says look upwards in the Visual-Tree and if you find any INavigationHandler use that - this basically allows you to default to the most immediate handler, just like in web-pages/IFrames, and it gives you the browser like use-semantic. And note, you can easily have containers-within-containers or use containers side-by-side, like in a master-detail scenarios.

Support for Error Pages

ErrorPage
One of the expectations with navigation-style apps is that when you can't get to any resource, you get a nice little exception page - well, in earlier releases that was not the out-of-the box behavior with nRoute. But with this release, we've not only added a default error page (shown above), but also allowed you to put in your custom page. Custom error pages are easy to create, all you need to do is to implement the aforementioned ISupportNavigationFailure interface - and you can set them by setting the ErrorUrl property on all built-in containers.

Also, the default error page can be reached via the Url "About:Error", and the WP7 counterpart looks a bit different as it's specifically tailored for the mobile experience - it even makes use of the active phone theme. And in cases where you don't want to show error pages at all, you can override the ShowFailedNavigationState method to handle a navigation failure in whichever manner suitable to your needs.

Introducing Controllers

One of the concepts in earlier version of nRoute was Url-addressable "Actions" - but now its got the axe, as it required that each action have a corresponding class, plus it wasn't represented in a strongly-typed manner. A replacement is in hand, have a look:

   1: [MapController("Shell/Tasks/{Action}"]
   2: public class ShellController : Controller
   3: {
   4:     public ActionResult Settings()
   5:     {
   6:         return new NavigateResult("Pages/Shell/Settings/");
   7:     }
   8:  
   9:     public void Exit()
  10:     {
  11:         Application.Current.Shutdown();
  12:     }
  13: }

If the above looks familiar, well then say hello to MVC in Silverlight - basically, we've got the full MVC style controller-action thing in nRoute. The idea is to have Url-executable actions, and Controllers provide us the necessary encapsulation required for something that is rooted in the UI. Additionally, we have the full range of extensibility points available in MVC, for example custom ActionResults, custom ActionNames, even custom ActionInvokers if you so require. And because this is build-upon the desktop-class routing engine you can even get the full MVC routing semantics, including setting custom route handlers with default values etc; or to keep your sanity just use the MapController attribute as shown above. Further, you can pass in action parameters to methods either through Url-tokens or using the parameters collection associated with the controller-action request.

Controller Behaviors

ControllerBehaviours
To execute Controller based actions we basically have the ExecuteControllerAction behavior, which can be attached to any sort of trigger. The use-semantics of executing an Controller is exactly the same as the NavigationAction (which was described earlier), and indeed they inherit from the same base-class. And the reason controller-actions optionally associate with navigation handlers, is because in some cases, they allow you to execute an action against an navigation handler.

Introducing SiteMaps

   1: <nRoute:Application.ApplicationLifetimeObjects>
   2:         <nRoute:nRouteApplicationService>
   3:             <nRoute:nRouteApplicationService.SiteMapProvider>
   4:                 <sm:XamlSiteMapProvider>
   5:  
   6:                     <sm:SiteMap>
   7:  
   8:                         <!-- AREAS -->
   9:                         <sm:SiteMap.Areas>
  10:                             <sm:SiteArea Key="ModuleA"
  11:                                  RemoteUrl="nRoute.ModuleA.xap"
  12:                                  InitializeOnLoad="false"/>
  13:                             <sm:SiteArea Key="ModuleB"
  14:                                  RemoteUrl="nRoute.ModuleB.dll">
  15:                                 <sm:SiteAreaInfo Key="ModuleA" />
  16:                             </sm:SiteArea>
  17:                         </sm:SiteMap.Areas>
  18:  
  19:                         <!- ROOT NODE -->
  20:                         <sm:SiteMap.RootNode>
  21:                             <sm:NavigationNode Title="Home Page"
  22:                                 Url="Pages/Content/HomePage/"
  23:                                 SiteArea="ModuleB">
  24:                                 <sm:NavigationNode Title="About Us"
  25:                                     Url="Pages/Content/AboutUs/" />
  26:                                 <sm:NavigationNode Title="Contact Us"
  27:                                     Url="Pages/Content/ContactUs/" />
  28:                                 <sm:ControllerActionNode Title="Exit"
  29:                                     Url="Shell/Tasks/Exit/" />
  30:                             </sm:NavigationNode>
  31:                         </sm:SiteMap.RootNode>
  32:  
  33:                     </sm:SiteMap>
  34:  
  35:                 </sm:XamlSiteMapProvider>
  36:             </nRoute:nRouteApplicationService.SiteMapProvider>
  37:         </nRoute:nRouteApplicationService>
  38:     </nRoute:Application.ApplicationLifetimeObjects>

Well, here's another nod to concepts from web-world, we've basically borrowed the concept of SiteMaps right from ASP.NET and indeed you get the same type of semantics of specifying hierarchical set of nodes. However, unlike ASP.NET, we have two specific built-in node types that directly relate to navigation and controller-actions (see NavigationNode and ControllerActionNode above). Also, this is an extensible architecture, so for example you can have ICommand based nodes or indeed custom ones based on your application executable-functionality.

SiteMapNodes

Above is a screenshot from a sample application (you can actually download it from Codeplex) that shows how you can use the SiteMap definition to integrate within your application. Alternatively, you could have menus or toolbars based on your SiteMap definition. Plus, to make life that much easier, build into nRoute are a couple of behaviors (see the diagram below) that allow you to execute any SiteMap Node. Also you can give each SiteMap Node a unique key, and use that to Navigate (see NavigateNodeAction) or execute the associated Controller-Action (see ExecuteControllerNodeAction) - this way you can abstract the Urls out.SiteMapBehaviours

SiteMaps are sourced using a "SiteMapProvider", which is basically tasked to yield a SiteMap. You specify the application's lone SiteMapProvider in nRoute's ApplicationService declaration (which is defined in App.xaml) - and so, when the app starts, nRoute tries to load the SiteMap using the specified provider. Built-into nRoute are two providers, one, a XamlSiteMapProvider which, as shown in the xaml above, allows you define the SiteMap in xaml itself. The other included provider is the XmlSiteMapProvider, it allows you to load the SiteMap definition from an external xml file. And to ensure maximum flexibility, the SiteMap infrastructure is designed to load asynchronous, so it can tolerate loading of SiteMaps dynamically/lazily. Furthermore, you can create your own custom SiteMap providers, like one perhaps using a database to dynamically assemble your application's parts at runtime.

Introducing SiteAreas

SiteAreaBehaviour Again I've borrowed the Areas terminology from  MVC, but in this case you can think of them as external resources (like xap/dll files), each SiteArea is uniquely identifiable using a key. The idea is to define all external resources in one well-understood place, so that both your code and the entire nRoute infrastructure can avail them at runtime. So for example, if you want to navigate to "Pages/Content/ContactUs" and it is in "ModuleB.dll", then by defining it as a Site Area and indicating the same in your navigation request (see right) the infrastructure will automagically load it when asked to navigate, and then navigate to your destination once the SiteArea is loaded. This way we get both easy-to-use semantics and very loosely-coupled bridges over external resources.

Now, in terms of the technical workings, when a SiteMap based external resource is requested, the navigation-engine will first check if the SiteArea (in our case) named "ModuleB" is loaded or not, if not it will download it, initialize any resources within it, and then continue with the navigation. All this takes place seamlessly, in fact if ModuleB had any dependencies (like "ModuleA" in the case above) they will be topographically resolved to the nth level. Also, the SiteMap infrastructure can also check for circular dependencies, just like Visual Studio does references.

Honestly, I don't think I could have made this any simpler, it is tightly integrated with the asynchronous nature of the routing engine and therefore works with anything build upon it, obviously like built-in navigation and controller facilities. However for other or custom uses you also have programmatic control over loading both SiteAreas and the SiteMap; and you can also specifically indicate which SiteAreas to load when the SiteMap initializes. Keep in mind, use of both SiteMaps and SiteAreas is totally optional, however, use of SiteAreas is not at all possible with WP7 because you can't load external resources by design. Lastly, note that SiteArea internally makes of RemoteResourceLoader component, which with this release has been totally revamped, and now makes use of IObservables to asynchronously load and map external resources.

Introducing Dependency Injection (DI)

nRoute already has an MEF like IoC component that is both extensible and open-ended, now, with this release it meets its significant other - an extensible DI system. The new DI systems' use can be summed-up by two attributes ResolveResource[Attribute] and ResolveConstructor[Attribute]. You put ResolveResource attributes on properties, fields and parameters; it optionally allows you to specify which named resource to use, and it also allows you to indicate as to if some resource is "nullable" in which case if not found it won't throw an exception. Further, in Silverlight you can only use it with public fields/properties, as use with non-public members is not allowed. And you use the ResolveConstructor attribute to indicate which constructor to use at runtime - its use is required unless you have a default public constructor, and in Silverlight you are obviously limited to a public constructor.

Now, like the resource "mapping" infrastructure in nRoute, the dependency "resolving" infrastructure is also totally customizable - if you want to provide your own custom resolving methodology, then inherit from the ResolveResourceBase attribute and provide your own custom implementation. Included in nRoute are two such custom resolving attributes, ResolveChannel attribute and ResolveViewModel attribute. The ResolveChannel resolves an Observable Channel, and the benefit of using it is that it bypasses the resource mapping layer and goes directly to the Channels infrastructure - plus, it allows you to specify additional contextual options. Similarly, the ResolveViewModel attribute can resolve an instance of the ViewModel for a View; note below how we appended that to the parameter of the constructor:

   1: public partial class PageA : UserControl
   2: {
   3:     [ResolveConstructor]
   4:     public PageA([ResolveViewModel(typeof(PageA)]Object viewModel)
   5:     {
   6:         InitializeComponent();         
   7:         this.DataContext = viewModel;
   8:     }
   9: }

This kind of extensibility moves beyond the traditional A is to B type of DI, as it is semantically-rich and can mesh your domain-logic seamless with the DI process - all the while keeping infrastructure concerns separate from the content. Further, note all resources created by the nRoute infrastructure like Services, Views, ViewModels, Modules etc can make use this DI system - so when defining your ViewModel you can ask it resolve services you require:

   1: [MapViewModel(typeof(PageA))]
   2: public class PageAViewModel : ViewModelBase
   3: {
   4:     private readonly IRepositoryService<Customer> repository;
   5:     private readonly Lazy<IMessageViewService> _messageViewService;
   6:  
   7:     [ResolveConstructor]
   8:     public PageAViewModel(IRepositoryService<Customer> repository, 
   9:         Lazy<IMessageViewService> messageViewService)
  10:     {
  11:         _repository = repository;
  12:         _messageViewService = messageViewService;
  13:     }
  14:     ...
  15: }

Locator Adapters for Higher-Order Dependencies

Another point of extensibility are so-called Locator Adapters, this is inspired by Common Context Adapters concepts which is all about abstracting out the IoC container specifics by using higher-order dependencies. For example, consider if you want to lazy-load a resource, normally you'll defer it's use till required, once require you check if it's null, if so then ask the IoC to load it etc - now this both quite messy and leaky, so instead why not have the DI resolve a Lazy<T> which would internally abstract away all the container and loading specifics - and you're level of involvement is limited to asking for Lazy<T> rather than a type T. Based on this simple but powerful concept, nRoute's DI can resolve the following higher-order dependencies, for any resource of type T.

  • T[]
  • Func<T>
  • Lazy<T>
  • Lazy<T, Metadata>
  • Future<T>
  • List<T>
  • ICollection<T>
  • IQueryable<T>
  • IEnumerable<T>
  • IEnumerable<Func<T>>
  • IEnumerable<Lazy<T>>
  • IEnumerable<Lazy<T, TMetadata>>
  • IChannel<T>

And if that's not enough, you can create your own custom adapters and register them with nRoute's Resource Locator Framework (RLF). Again, like the MapChannel attribute we saw earlier, you can extend the DI to your custom domain specifics, just as we do with IChannel<T> above. Another interesting adapter is the Future<T>, which when used says that we might not have this resource-type available as of now, but in some point in the future it might be - so just resolve a Future<T> resource and we will check against it if the resource is available or not (via its IsValueAvaliable property) prior to using it - using this you've abstracted away the IoC/DI system specifics.

Another problem with DI in an open-ended IoC framework like MEF and RLF is we have no idea what is a resource and what is not; MEF deals with this by rejecting the composition, nRoute deals with this by throwing an exception - simply because without a resource-type registration we don't know if type XYZ is a bonafied resource or not, and we simply can't accept anything is a resource policy, as that's an endless loop. Now to solve this conundrum, keeping in mind the open-ended nature of nRoute, we have a special MapAsKnownResource attribute (with a parallel DefineAsKnownResource attribute) which tells the RLF that this type is a known resource type, and so accept any request for it. This way we can reject any erroneous-requests, but still accept the unknowns.

   1: [MapAsKnownResource]
   2: public interface IExecuteService
   3: {
   4:     void Execute();
   5: }

So for example, with the code above even if we don't have any registered implementations of IExecuteService, we still accept it as a bonafied resource type because it is specifically earmarked as such. Note, normally you don't need to put this on every resource because you'll have an implementation available at the same time - in case you don't, use this.

Dependency Recomposition Support

Dependency recomposition is a fantastic facility, however it is something that can without due-consideration lead to all sorts of memory leaks, because in most likelihood you are tying a variable to a static "source-of-resources", whose lifetime will mostly likely exceed that of your variable. So for recomposition with RLF, I've made available three specific adapters that "by default" will not lead to memory leaks as it makes use of "smart handlers" infrastructure in nRoute. The three supported adapters for a resource of type T, are:

  • ReadOnlyObservableCollection<T>
  • ReadOnlyObservableCollection<Lazy<T>>
  • ReadOnlyObservableCollection<Lazy<T, Metadata>>

Now this is not a be-all list, as  you can extend it with your custom adapters as you require - but I think for most common uses these should suffice. Its usage is similar to any resource, and doesn't require any additional opt-ins:

   1: public class ServicesViewModel : ViewModelBase
   2: {
   3:     [ResolveResource]
   4:     public ReadOnlyObservableCollection<IExecuteService> Services { get; set; }
   5: }

As you would know, ReadOnlyObservableCollection implements INotifyCollectionChanged, which therefore can be used to notify when recomposition happens and to stop the recomposition one just needs just nullify the variable/property (note, nullify all instances of it, and also remember to remove any event-handlers attached to the collection to stop recomposition).

Observable Channels

We've made sweeping changes to the Observable Channels in nRoute -  for the better - the performance is up 4 fold, we've aligned it much more with the Observable pattern, and now we also have compatibility with Rx-framework.

IChannel
Each channel is now defined as an IChannel<T> (as can be seen above) and in Rx-speak an IChannel is a Subject which means it both an observer and observable. And being both an observer and observable means that through an IChannel you can both publish and subscribe - which is the same as before, but now you can direct do using the IObservable<T> and IObserver<T> interfaces. A new thing with this release is that you can also publish exceptions (using OnError) and this is appropriate because, as I explained before, a call to any operation in .NET has two possible outcomes an explicit result or an implicit exception, and the same two possibilities are reflected here. One important thing to note is that you CANNOT call OnCompleted on an IChannel because an observable channel is usable through-out an application's lifetime, doing so will only raise an exception.

A new thing with this release is that we have the concept of a public and private channels - each type of channel has one default public IChannel<T> associated with it, and additionally you can any number of private channels each identifiable with an unique string-based key (non-case specific). The API is very simple, below we are subscribing and publishing on a public channel and a private channel (identified with the key "Test"), have a look:

   1: // Subscribe
   2: Channel<string>.Public.Subscribe((m) => MessageBox.Show(m));
   3: Channel<string>.Private["Test"].Subscribe((m) => MessageBox.Show(m));
   4:  
   5: // Publish
   6: Channel<string>.Public.OnNext("Hello Public World!");
   7: Channel<string>.Private["Test"].OnNext("Hello Private World!");

Now above the "Subscribe" is an extension method, and you have couple of them with lots more options. Further, the OnNext method (and OnError method too) has an overload that takes in a Boolean suggesting as to if you want to publish it asynchronously. If this is not not enough you can always call in the cavalry, in form of Rx-framework, so for example:

   1: Channel<string>.Public.
   2:     Delay(TimeSpan.FromSeconds(10)).
   3:     TimeInterval(TimeSpan.FromSeconds(5)).
   4:     Select((t, m) => m.Substring(10)).
   5:     ObserveOn(DispatcherSynchronizationContext.Current).
   6:     Subscribe((m) => MessageBox.Show(m));

So above, we are delaying the listening by ten seconds, and at every five second interval we are selecting a substring of the first ten characters, and observing it on the dispatcher thread, to show the resulting string via a message-box - nonsense use, but the point is you get the full power of the Rx-framework for use with your channels. Though note Rx-framework is not required by default, but you have the option to exercise it if required (aka nRoute doesn't have a dependency on Rx, but we have binary compatibility).

Old Channel Ways Survive

Despite the new API I've show above, you can still use the old-style API to publish/subscribe against observable channels (like before) - and it has full parity to the new API. And as an extended use-case it even allows non-generic usage of channels, which can be really handy sometimes.

ChannelObserver
The Channel static class follows the "publish/subscribe" metaphor, and its usage is also quite simple:

   1: // Publishing through the Channel class
   2: Channel.Publish<string>("Hello Public World!");
   3: Channel.Publish<string>("Test", "Hello Private World!");

Now one of the big internal change to channels is that now by default all subscriptions are NOT weakly referenced - they are strongly referenced and must be manually disposed/unsubscribed. This change was required for both Rx-framework and use of lambda statements, as by their nature lambda's can't survive a weak-reference subscription (technically, they can by lifting some reference into their scope, but that's leaky design) - which meant that they would have unsubscribed as soon as you exited the method they were declared in. However, if you know what you are doing, you can still make lambdas weakly-referenced, using an overloaded subscription method. Despite this change, the ChannelObserver<T> by default still by maintains a weakly-referenced subscription, which is exactly like before - and in fact, I still highly recommend the use of ChannelObserver<T> in your Views/ViewModels as you normally wouldn't want to deal potential memory leaks if you did not unsubscribe. Remember channels (private or public) are static resources, and their lifetime spans that of the application - so when you hitch something to it, you are also potentially extending the attaches' lifetime to match that of the channels (Hello, Memory Leak).

ICommand Infrastructure Updates

Earlier we had this distinction between so-called ActionableCommands and ActionCommands, well no more - we've unified the two, and now we just have ActionCommand and ActionCommand<T>(.) Also, I've done bit a of clean-up under the hood, particularly I've abstracted the ICommand base-classes which can now be used to make stand-alone commands (I'll show a nice use-case in a separate post).

TriggerParameter Now, one of the common questions I get asked is how do we pass-in event-arguments to the ViewModel, well the simple answer is that you don't. An event-argument is a View-specific construct, it has no place in the ViewModel, obviously because separation of concerns is the entire point of View-ViewModel partition. That being said, in case where "data" from the event-argument has to passed-onto the ViewModel, we now support that via the new TriggerParameterConverter property (see right) on the ExecuteCommandAction behavior.

TriggerParameterConverter accepts an IValueConverter, which converters the Trigger's parameter for use as the Command's parameter. I hope that is not confusing, what happens is each trigger gets to pass onto its to-be-triggered action(s) a parameter, and in the case with EventTrigger (used above) it passes in the event argument from the selected event (in this case selected above that would be the SelectionChangedEventArgs type). And by specifying the converter for converting SelectionChangedEventArgs to something the ViewModel can understand and digest, we are able to bridge the View-ViewModel separation without violating the separation agreement. Moreover, this works with all sorts of triggers, and remember each trigger passes-through whatever is appropriate to its operation, so in this way we have a very flexible approach that works across the board and not just with events.

New Behaviors and Triggers

UpdateBindingExplicitly I've added three sets of new behaviors, the first of which is called UpdateBindingExplicitlyAction - it as the name suggests allows you to update a property binding explicitly. Consider the example in the screenshot to the right, it shows a TextBox to which we've attached our UpdateBindingExplicitly action. Now, what we're saying there is that whenever the TextChanged event occurs, update the binding for the property called "Text". It's as simple as that - note you can pair the update action with any sort of of trigger, and it will update any (non-read only) dependency property's binding.

The second new action is SetFocusAction (and an accompanying TargetedSetFocusAction); this action allows you to set the focus on any element by pairing it with a Trigger. In fact this is often a common newbie question, how do you set focus in a MVVM application? Well, here is one simple and designer-friendly answer.

The other two new behaviors are BoolValueDisableBehavior and NullValueDisableBehavior, they both allow you to disable or pseudo disable an element depending on a Boolean value or a Null value. This actually tackles an acute problem in Silverlight, where most of the controls don't support an IsEnabled property, and so you can use this behavior to gloss over the differences by disabling input and reducing the opacity in cases where the control is not inherently disable-able. For example, below is a Border control (in Silverlight it doesn't have an IsEnabled property), that is automatically "disabled" when there is no loaded worksheet in the backing ViewModel.

PseudoDisabled

The xaml for this looks like:

   1: <Border ... >
   2:     <i:Interaction.Behaviors>
   3:         <nBehaviors:NullValueDisableBehavior Value="{Binding Worksheet, Mode=OneWay}"/>
   4:     </i:Interaction.Behaviors>
   5: </Border>

Woo, Finally

For a 128kb/75kb (Full Framework / Toolkit Version) additive to your xap files, I think nRoute packs a punch - and with the new release it is more wholesome than ever. Definitely, we still have a long way to go, but I think the big difficult steps have been made. And the focus here forth will not be so much on features but better execution and quality, and for the immediately proceeding release Designer/Blend support will be the big go-go. And finally, finally, a lot of the new features in this release have come from user's suggestions and pain-points (thanks guys), and so I encourage anyone and everyone with feedback to chime in - there is a receiver on the other end.

You can download nRoute (all three versions) from Codeplex including the source
- Targets Silverlight 3 for Web  (Silverlight 4 version will be out once RTM tools are posted)
- Targets Silverlight 3 for Windows Phone 7
- Targets .NET 3.5 for Desktop (.NET 4 version will out with Silverlight 4 release)

Note, we have 6 dlls, 3 for nRoute.Framework and 3 for nRoute.Toolkit

nRoute Dependencies
- System.Windows.Interactivity.dll from Blend SDK
- System.Observable.dll from Rx-framework
 
View the Officer Xcel Demo App, source is also available on Codeplex
more samples to follow

PS: I want to specially thank Carlos Álvarez, he really helped me with throughout the way, especially with the WPF version - it wouldn't have been possible without his support. You must check out his WPF Chronos Framework, its designed for developing (super) MDI applications using Windows Presentation Foundation.

Posted by Rishi on 13-Apr-10 1:36 PM, 22 Comments

Categories: WPF, WP7, Silverlight, nRoute
WP7Shot1

WP7Shot2

Well, that was painless - nRoute, a forthcoming version, is now running on WP7S and with surprisingly very little omitted. The only thing that got the full-chop was a remote resource (dll/xap) loading helper class other than that just some nip-tucks and if-elses did it.

I'll be releasing toolkit version for the Silverlight, Desktop (.NET 3.5) and WP7 next week, and I'm very existed about some of the new features added. Stay tuned.

Posted by Rishi on 17-Mar-10 9:52 PM, 49 Comments

Categories: nRoute, Silverlight, WPF

WP7 
Windows Phone 7 Series - Edgy yet Elegant

iPhone

iPhone - Popular and Classy

Android_thumb[3]

Android - Techies United

Palm_thumb[1]

  Palm - Got its Own Thing Going

Symbian_thumb[4]

  Symbian - People's Choice?

WindowsMobile

 Windows Mobile - Yawn, Boring

Posted by Rishi on 15-Mar-10 5:55 AM, 109 Comments

Tags:
Categories: General

WP7Sudoku

Sudoku

Couple of weeks ago I had created a Sudoku Game in Silverlight and dressed it up in iPhone's theme, I even posted the code on Codeplex. Now, yesterday with some time on my hand and WP7 expectations running high I took the same codebase and by just changing the main view's XAML in Blend, I re-dressed it in WP7's theme. It's not pixel perfect and the animations need work, but I think we have a reasonable WP7 metro-theme inspired implementation in something that took less than 3 hours of work. Moreover, the iPhone version and WP7 version apart for the visuals are absolutely the same, the backing ViewModel code is without a single change and they both offer the exact same functionality. This is a testimony to both the benefits of a MVVM design (even with games) and also to nRoute framework, upon which both these demos were made.

WP7ViewServices
ViewServices 
View the Window Phone 7 Series Version: http://www.orktane.com/nRoute/WP7Sudoku/
View the iPhone Version: http://www.orktane.com/nRoute/Sudoku/

Note: The WP7 Sudoku demo makes use of "Segoe UI Light" font, and it must be installed on your machine else it will default to the Silverlight's portable font.

Finally, please vote below for which ever design you think is better.

Posted by Rishi on 14-Mar-10 12:20 PM, 31 Comments

Tags: , , , ,
Categories: nRoute, Silverlight, UX