This awesome stuff is from the talented hand of Jonathan Jarvis. More info here.

Seriously though, if possible I next want him to visualize the Middle-East mess! The generational short-sightedness and lack of understanding can do with a big-picture reflection - which a visual such as this can provide, to perhaps some benefit.

Posted by Rishi on 24-May-09 11:40 AM, 18 Comments

Tags: ,
Categories: General, Art

In my recent post I went through various design aspects of nRoute Containers, albeit without a single line of code - as a counter, I showed a demo specifically for Containers dubbed Office® 2010 (or more correctly Officer 2010). In this post I'll go through the Officer demo app, and like with my previous "step in" post, I'll enumerate various items in a point-by-point fashion, relating them to Container related use and design concerns.

Note even though we are aping Microsoft Office 2010 visuals, the demo app is not designed to reproduce office type functionality - it is just an exercise in learning. Screenshot for Microsoft Excel 2010, below:

Microsoft Excel 2010 Screenshot

And below are the Silverlight 3 version screenshots, click here to run the demo app (requires Silverlight 3).

Officer 2010 Screenshot 
Officer 2010 Screenshot

Application Structure

Officer 2010 Solution StructureOne traditional but important type of "separation of concerns" is componentization, and assemblies are often the physical manifestation of such separation. Because the Officer app is rather shallow, there is no great story as far as componentization goes, still I've separated the app into three projects - shell, content and infrastructure related projects. The infrastructure is basically controls and components common to all, the shell is the silverlight "application" that hosts the root visual and styling content, and the content project quite self-descriptively houses the content. 

However the point of having three projects was to highlight the possibility of dependency-mitigation using the Url-based mediator. For example, apart from a single line of code there is no dependency between the shell and the content project. The single line of code (line  18, below), is just used to register the navigation mappings but can equally be rigged in multiple other non-dependent ways. For example, you could dynamically load the content assembly and then ask it register the mappings, or a better approach would be to use something like Prism which offers bootstrapping and module-based initialization entrapments within which you could set the mappings.

The Application Class

The application class as I have mentioned multiple times is conveniently hijacked in nRoute to host a so-called application-wide default container - which by definition handles any navigation without a specified handler. In this case we use the build-in StatefullApplication class, onto which we set the RootVisual and the NaivgationContainer properties as shown below.

public partial class App : nRoute.Navigation.Application.StatefullApplication
{
	private void OnStartup(object sender, StartupEventArgs e) 
	{
		// we create the shell
        var _shell = new Shell();
        this.RootVisual = _shell;

        // we set the default container and set the shell's data context
        this.NavigationContainer = _shell.PresistentContainer;
        _shell.DataContext = this.GetApplicationLinks();

        // we can customize this using deep-linking or something - but for now it is static
        _shell.LinksListBox.SelectedIndex = 1;  
        
        // and we map the assemblies - this is strongly typed, but you could do it many other ways
        ActionService.MapAssemblyActions(this.GetType().Assembly);
        NavigationService.MapAssemblyRoutes(typeof(Officer2010.Content.Views.NewDialog).Assembly);
	}
	// .. other code
}
The code above should be self-explanatory apart from the GetApplicationLinks call and setting index on a list box - which I'll get to below. Note, here we not enabling deep-linking or browser-shell integration, both of which are normally setup at the application class level - though it is perfectly doable.

Navigation Structure

Navigation Structure If you look at the navigation control (shown on the right), it has a set of primary nodes which are both navigable and selectable. However a bit unusual is that it also headlines a couple of links that seemingly are functional and not navigational in nature - like save or open. To represent this structure, I just created two POCO classes, with the primary nodes (Link class type) mapped to navigation Urls and its children (of LinkAction class type) mapped to action Urls. Further, a list of the primary nodes, yielded by in the GetApplicationLinks method in the App class, is set as the DataContext of the root visual (Line 11 above).

The navigation controls is just itself a common ListBox, with a custom ItemTemplate and importantly a customized ItemContainerStyle. And since we know the binding structure, the templates bind to the relevant properties, they also make use of nRoute behaviours attach the navigation and action Urls (see LinksListResources.xaml). Just as a side point, the ItemContainerStyle holds the Lists control's template for the mouse-over and selected visuals, though customizing it is a bit inaccessible in Blend - to customize use the Object > Edit Other Styles > Edit Item Container > . menu hierarchy.

The Shell Structure

The structure of Shell.xaml is really simple, it is basically 3x3 grid with basically a left-anchored list box, a flexible-width container, and a persuado back button up-top. The image below outlines the layout structure:

Click to Open

Custom Containers

With this demo app I wanted to highlight two customization points with Containers, styling and state-management. Because containers by definition model their state related behaviours, I wanted to create a container that could persist its state in Isolated Storage on exit and resurrect it on start - however that was not to be simply because in SL we can't arbitrarily serialize objects, so in a future release I'll do the necessary tinkering with the state management classes to hopefully get this scenario working (however this in entirely possible in WPF). Nonetheless, in the code you'll see how we can still use the isolated storage to persist data, however on a page-by-page basis.

The styling customization was easy pickings; firstly I wanted to put in place some navigation-induced transition effects for which I created a custom control-template that wrapped the presenter in Silverlight Toolkit's transition control, you could also easily use other libraries such as Silverlight FX.

<!-- TRANSITION CONTENT CONTROL WRAPPER -->
<toolkit:TransitioningContentControl RestartTransitionOnContentChange="True">
    <ContentPresenter/>    
</toolkit:TransitioningContentControl>
The other visual tweak I did was to use the SL3 specific child window for highlighting navigation failures, this has much better aesthetics than the MessageBox approach used earlier - try clicking the "Back" button. Lastly, one stupidity I've done with the Containers API is to expose ICommand based properties to trigger navigation, which ensured very clumsily use semantics; so in the custom container I've somewhat correct that by exposing a simple Url property that triggers navigation when changed.

Sub-Containers

One of the common user-cases involve having container like regions within a page, which itself is hosted in a container - that is nothing special really, but with nRoute you get nice-clean and loosely-coupled contraption to play such scenarios out. For example in the NewDialog.xaml page (shown below) we have two lists of document templates (highlighted with yellow diagonal boxes); selecting any item on either of the two ListBoxes triggers a command in the ViewModel, which in turn causes navigation in the sub-container (shown with red stripes) - that then shows the selected document template's details page. The commands are exposed as properties on the ViewModel, and bound to the ListBoxes' SelectionChanged event using nRoute behaviours, and the sub-container is bound to an "ActiveTemplate" property of the ViewModel.

Click for Larger Picture

One of the other useful aspects to sub-containers is that the DataContext of the "host page" flows in the sub-container and any of it's active content, unless specified otherwise. I've used this DataContext inheritance behaviour in OptionsDialog.xaml (shown below); the options page displays Common and Advanced Settings in a sub-container. To hold the settings data I create two POCO classes (the CommonSettings and AdvancedSettings types) and exposed these on the host page's ViewModel as properties. As these two properties "flowed" into the sub-pages, they were used to bind the settings on various UI controls - which really helped, as I didn't have to create extra ViewModels or manage extraneous data exchanges. Also, the POCO classes were earmarked with the DataContract and DataMemeber attributes to enable persistence using the Isolated store in SL, which enables your custom settings to survive multiple disconnected sessions - try it. 

ContainerDataContext

Fishing not the fish

In summary, I hope I've shown the use, design, and customization aspects of Navigation Containers - because they really help in logically breaking-down your application and compose it together as a loosely-couple but cohesive unit. So the real take-away should be how you model your application's visuals using containers as a fundamental building-block - in wiser words the fishing as opposed to the fish itself.

To run the Officer® 2010 app, click here (requires Silverlight 3 runtime).
To get nRoute and Officer® 2010 source code, click here.

PS: The detailed Officer demo app is not a showpiece for architecture or coding practices - it was specifically designed around highlighting certain nRoute concepts. Also, you will be pleased to know no code-behind was harmed in the making of this demo.

Update: Recompiled and updated the source for SL3 RTM version

Posted by Rishi on 22-May-09 8:55 AM, 16 Comments

Categories: nRoute, nRoute, Code, Code

With little Chinese naming ingenuity I present to you Office® 2010, the proper non-Chinese name being Officer 2010, in Silverlight 3. It is based on the the new opening screen in Microsoft Office 2010, and designed specifically to showcase nRoute Containers which I blogged about in my last post.

First, below are some of the reference screenshots from Microsoft Office 2010 apps.

Microsoft Word 2010 Screenshot

Microsoft OneNote 2010 Screenshot

And next are some screen captures of the demo app.

Officer 2010 Screenshot 1 

Officer 2010 Screenshot 2 

Officer 2010 Screenshot 3

To view the actual Silverlight sample, click here - it requires the Silverlight 3 runtime. As far as creating the application is concerned, I did it over two days using Visual Studio and Blend 3 Preview.

Do note this is not a functional application per se, and is not designed to mimic Microsoft Office Suite functionality - it is again, produced to demonstrate the concepts pertinent to nRoute. And since I've never used Office 2010, I can't speak to either the visual-accuracy or behaviour-similarity, plus the lack of fit and finish is quite obvious. Also, you will often run into the acknowledging request balloons, and by clicking the "Back" button up-top it will "showcase" an error - by design.

For a technical overview of this demo app, click here.
And to download the code,
click here.

Posted by Rishi on 19-May-09 12:34 PM, 22 Comments

Categories: nRoute

Think HTML's IFrame, is perhaps the easiest way to describe what nRoute navigation containers are and do - or simply put when we navigate we do so in a container. Also, as I have mentioned enumerable times before, with nRoute we abstract content and resources as Urls, and in a yin-to-the-yang kind-of way navigation containers represent the realization of those abstractions. 

Overview

Below is the class-model for various navigation containers (hereon referred to only as containers) in nRoute.

On the left side of the diagram above are the interfaces that represent the functionality availed by the containers, and on the right are the usable controls that implement the interfaces. The reasons for interface based implementations is primarily to enable instance-less representation and also to enable tacking the container-related functionality onto existing controls - both these points are highlighted below.

INavigationHandler

If you look at the NavigationService API you'll notice you don't actually need any of the pre-defined containers to handle a navigation request - all you need is an implementation of the INavigationHandler interface. This interface's responsibility is to handle navigation responses, and it has a very simple signature - it contains two methods, the ValidateRequest method ascertains as to if the handler can process the request, if true then the ProccessResponse method is given the response to handle.

Now, normally you would use the specialized containers controls that implement the INavigationHandler and other related interface, however it is also possible to append this interface on existing controls to turn them in containers like a stack panel or list box. Further, it is also possible to use this interface and the navigation facilities in a non-visual context - like using it with the ViewModel however semantically it is not designed for such use-cases.

INavigationContainer(s)

The INavigationHandler interface mentioned above represents the bare-essential as far handling the response is concerned; however containers normally have richer use semantics and that is what the INavigationContainer interface encapsulates. The API is for the most part self-descriptive, it basically appends the INavigationHandler with informative events, state properties, and navigation-related methods.

Moreover, we usually build upon the INavigationContainer interface to create specialized containers such as the IBrowsingContainer - the idea of having specialized containers is to encapsulate different navigation-model functionalities such as back-forward navigation or history trails. Currently, out of the box in nRoute you get four usable container, implemented as controls and which I described earlier as follows:

NavigationContentControl This is essentially a bare-bone and light-weight container based on the content control type, it can handle a navigation response but that's about it. It offers no events, history, or state related functionality - basically it has none of the richer use semantics present in an INavigationContainer implementation. Think Vanilla Light.
NavigationContainer This is also a simple and basic control that inherits and extends the NavigationContentControl, but it offers richer use-semantics based on the aforementioned INavigationContainer interface. However, it stores no history or state, and it simply navigates onwards from one Url to another. Think Direct and Onwards.
BrowsingContainer This builds on the NavigationContainer control, and offers web-like behaviour and state management features. Basically, it stores a stack of back and forward page's info with state - akin to an Internet browser. It enables back and forward navigation based on the stored history, and allows purging of the history and state. Think Very Web-Like.
StatefullContainer This container also builds on the NavigationContainer, but stores state for any page you have visited - the state is restored onto the page once you navigate onto it again. It doesn't have back or forward stacks, it only keeps one list of states - so simply your last saved state is restored once you navigate to the same page. Think Good Memory.

The build-in containers cover most of the common use-cases, however the buck doesn't stop there - because it is relatively simple to create your own containers. And the benefit with custom containers is that you can precisely gear the container to whatever use-semantics your scenario mandates - see my forthcoming post for some samples. Also when designing your

State-Management

One of the important use-semantics that containers exhibit is state-management - which basically involves saving and restoring the content's contextual (and visual) state. This is an opt-in feature that the content can participate, however it is the container's mandate in as far as using, applying, and maintaining the states is concerned - so if the container (like the NavigationContentControl container) doesn't administer state-management then the content's participation becomes irrelevant. Further, the container defines how and when the state will be administered - so for example the BrowserContainer only restores the content state when navigated back or forward, and not when you navigate to a new Url.

The figure above show the opt-in API for participating in state-management - it does three things, one initialize the state with the passed-in name-value collection, two save and restore state on demand, and lastly provide for a content title. The initialization part which I described in an earlier post gets passed in a merged name-value dictionary consisting of the navigation request's name-value collection, the default parameters name-values set while defining the route, and the parsed tokens' name-values from the Url. Note, this is separate from the ISupportRestoreState interface - which asks for a name-value dictionary to save the content's state, and that same state is later passed-in when restoring the content's state.

Though the opt-in mechanism for supporting state is rather "manual", it is also quite simple and low-impact as opposed to reflection based approaches. Also, one other nice thing about the opt-in interfaces is that you can use these with your ViewModels, which makes for a tidy integration story. Lastly, the opt-in feature also helps with the "separation of concerns" principle I've been harping about - the containers are only responsible for managing the states, whereas the content is responsible for extracting and using the state.

Composition 

In my last post, I highlighted the composition capabilities brought to bear by nRoute - and without repeating myself, I'll just mention that containers are the fundamental building-blocks for composition in nRoute. However, the important thing to understand (and apply) is how you can construct and combine containers to create various use-models such like parent-child or tab-like constructs. See the demo app's technical overview, wherein we create a so-called workspace/blades model by composing a number of containers together. Also, as the container is only "tied" with the content at run-time, it gives you enormous flexibility and control as far the composition is concerned, independent of the content itself.

Default / Application-wide Containers

One of the common scenario with the use of containers is to annotate a default/application-wide container - which when processing navigation (without any specified target container) is automatically used to handle the response. To house a reference to the default/application-wide container we use the Application-class derivative (by default App.xaml), because it provides a well known host to similar application-wide functionality. For all the build-in containers we have corresponding Application-class derivatives, as shown below:

You might have noticed that the Application-class derivatives above specifically implemented the container's defining interface (e.g. IBrowsingContainer on BrowsingApplication type), the reason for that is to make the application class a fully-implemented proxy of an actual container (which would be in a VisualTree on some Page). This might look somewhat confusing, but what it allows us is  to swap the actual container, without breaking the event-references or direct reference to the default/application-wide container represented by the Application derivative. With this behaviour you could enable tab like containers; in fact the demo app uses this proxy-type behaviour for setting the active workspace/blade as I explained earlier.

Two other thing enabled by using the application-level containers archetype is browser shell-integration and deep-linking support, however I'll have to cover those aspects in a separate post.

Behaviours

nRoute comes with a wide-array of navigation related behaviours build-in, and these behaviours when triggered automatically try and resolve a container to handle the response. The logical sequence to resolve the container is as follows; firstly, if you have specified the handling container (either by binding or by specifying an ElementName) it will just use that, and it's done. If that is not specified, it will look in its visual tree first and try and find the first parent that implements the INavigationHandler interface. This also means that it kind of works like a browser whereby when you click a link the hosting container (like the Html Page or IFrame) handles the navigation automatically for you, unless specified otherwise. If no handler is found in the parental visual tree, it will look at the current application object and see if a default/application-wide container is specified and use that. If it doesn't find a container at the application level, well it gives up and throws an exception.

Parts & States Model

Lastly the build-in containers use the parts and states design model introduced with Silverlight 2 - this enables you to customize both the visuals in various "navigation-states" as well as the transition effects in the course of the state changes. Also, the inheritance-root for all the containers squares up to the content container type - which as you known allows for a custom look-and-feel. One other point for customizing the visuals is the "ShowFailedVisualState" protected method - by default it shows a message box when the navigation fails, you can override it to customize the error visuals.

This concludes another part of the documentation for nRoute, however I am going to follow this post by a couple of examples that demonstrate the customizability and composition capabilities of the container infrastructure in nRoute.

Posted by Rishi on 15-May-09 10:14 AM, 9 Comments

Categories: nRoute

Lately, its been raining M-V-VM (Model-View-ViewModel) in the SL and WPF world, and rightfully so because M-V-VM to me is the best pattern for application-development given the features in SL and WPF. Now, in this post I'm not going to introduce or detail the pattern itself, read this article by Josh Smith for a great intro, rather I'll go over what nRoute (download here) brings to the party as far as M-V-VM is concerned. And this is significant because nRoute was specifically, but not exclusively, designed for use with M-V-VM.

Separation of Concerns

From a larger perspective, M-V-VM is based on a simple principle of "separation of concerns" - in this case between the consumable View and the View's State and Behaviour which is represented by the ViewModel. However, it is important to appreciate that the ViewModel is not a dumb conductor, rather it is a contextually and state-fully rich orchestrator (which inturn makes the View as "logic-free" as possible). This separation also plays into enhancing the Developer-Designer workflow Microsoft has been touting for sometime.

Further, in my previous post about the demo app I explicitly tried to highlight how nRoute helps in another type of separation of concerns - between the infrastructure faculties and the actual actionable/usable content. Using Urls as a abstraction over content, nRoute dynamically binds together the infrastructure and content into a consumable application. The critical benefit being that infrastructure and the usable/actionable content can be clinically separated and evolved independently of each other.

This whole range of separation of concerns, with the traditional n-tier and domain-model helps create a flexible application and infrastructure - perhaps more complex, but one that will stand the stress-of-change much better.

Mediator

Central to nRoute is the routing engine, which is a direct port of the engine found in ASP.NET 3.5sp1 or MVC. It plays the role of a mediator that uniquely identifies resources using Urls, which are used for both composition and navigation purposes. In addition to a "resource locator" role the mediator also has another important role, which is that it allows for loosely-coupled dependencies amongst resources. When I say dependencies amongst, it can either be of composition nature like parent-child windows, or it can be of linkage nature like in wizards screens - both of which are discussed below. Also appreciate that because the mediator in nRoute uses string based Urls to resolve dependencies, your resources can evolve independently of each other akin to say HTML pages on a Web server.

Often people find the use of strings as locators a bit too loose of an abstraction, however Urls in nRoute are not magic-strings rather they have to be formally registered and properly formatted too. And equally the fact is that Urls are perhaps the most successful and all-encompassing form of resource locators in use. Further like MVC et al., Urls in nRoute support tokenised fragments which makes for even easier and broader use semantics.

Composition

Increasingly the metaphor of a "Window" is taking a back seat to the metaphor of a "Page", because with the success of the Web-Page model the window metaphor easily breakdowns in the face of web-like fluent user experiences. And though, it is not technically hard to achieve composition in its simplest form, what has historically hurt is the lack of a proper/built-in composition model. Further the complexity and clumsiness of solutions like Regions in Prism or WPF Frames hasn't helped, that is without even considering the locator, state-management, and navigation type issues the page metaphor brings.

And in this scenario, nRoute really shines because it brings a simple and well-understood model for composition using Urls, along with inherent support for state management and navigation features. The composition model in nRoute is akin to IFrames in HTML, and as suggested it makes use of so-called "container controls" (or simply containers) which by design exhibit different state-management behaviours (like Back-Forward History). Build into nRoute are four such container, plus the container model is fully customizable/extensible to accommodate custom needs. Now, what is profound here is that your content doesn't need to be aware of the container or vice-versa, because nRoute makes the composition magic happen without direct dependencies.

Further, like HTML pages/IFrames you can have one container within another, which allows for Master Pages or Parent-Child Pages type of use models. Alternatively, you can place two or more containers next to each other (each container individually addressable) to get something like the antiquated FRAMES model in HTML. In all, with the composition model in nRoute gives you a boat-load of flexibility coupled with a high degree of loose-coupling between the infrastructure and the content.

Navigation

With composition, navigation has always been the bane - but by using Urls it becomes both simple and easy to effect. Further, nRoute features an extensive range of behaviours that extend navigation to almost all control's common events, and accompanying that is a simple NavigationServices API. And depending on your preferences you can either drive the application-flow via code in the ViewModel or in the xaml based View. Additionally also supported is a concept-of an application-wide default container for navigation purposes, which comes into play in deep-linking scenarios.

State-Management

Interlinked to navigation is state-management, which in nRoute is an opt-in feature driven by a simple interface called ISupportNavigation. Within a M-V-VM archetype, you can implement the said interface in the ViewModel, and equally use it for both saving and restoring state independent of the View. Furthermore, the ISupportNavigation interface helps formalize the passing of tokenized parameters (and optionally a name-value collection) in the course of navigation. The benefit of state-management vis-a-vis navigation is that the lifetime of any View is limited to it being active in a container - however the content state can be persisted independent of the View.

Commands

Because of the nature of M-V-VM separation of concerns, the command-model gains added prominence in achieving the View and the ViewModel interaction pattern. And nRoute features first-rate support for both creating and consuming ICommands - it has an expansive implementation of non-routed Commands and behaviours to enable its consumption. The ICommand implementations which I blogged about earlier, features a strongly-typed parameter, INotifyPropertyChanged notifications, enabling/disabling the command, and a bindable command parameter property. Further, like in the case of navigation, nRoute features an exhaustive range of behaviours for consuming ICommands, which can respond to almost every control's common events.

Actions

Actions in nRoute are Url addressable functionality, that execute off the UI thread - this is useful for things like triggering some downloads or enabling pub-sub type of communications. The model for constructing actions is relatively simple, it is based on an interface called IActionHandler and the consumption pattern like earlier is based on attachable behaviours or alternatively by the use of the ActionServices API.  Further Actions support multi-casting to one or more globally registered handlers, and because of the loose-coupling it's a form of Weak Eventing using Urls. Also, you can direct an Action request to a specified handler which can be real handy sometimes, as described below.

In a way you can think of Actions in nRoute as mediated ICommands that can be addressed, in a loosely-coupled fashion, via Urls. And like ICommands, you can expose Actions in your ViewModel using a Delegate-Command type property (see the DelegateAction type), and on the View side you equally could bind to the Action property for use with behaviours. Further, like navigation Urls the actionable Urls also supports tokenized Url fragments and additively a request can be furnished with a name-value collection parameter for greater flexibility.

ViewModel Injection

One of the obvious to-dos with M-V-VM is injecting the ViewModel into the View - and because in nRoute the Views are instantiated by the mediator it gives us the perfect opportunity and place to inject the ViewModel. There is a build-in attribute-based approach to this, which uses the wordy MapViewModelViewNavigation attribute to set the ViewModel as the DataContext of the View. However, you are not constrained to use this attribute, you could easily create your own attribute-based implementation that say uses a service locator to determine and inject the ViewModel. Further, if you know MVC then you'll appreciate how much can be done by creating a custom IRouteHandler, and in nRoute using the IRouteHandler extension point you could totally lay out a custom M-V-VM implementation atop nRoute.

Service Locators

One of the common tripping points with M-V-VM is the use of platform specific and/or task specific functionality like MessageBox or File Dialogs in the ViewModel. The solution for the same is wrapping the functionality in a platform/task agnostic way into a locatable service; however this begins to creep mightily into the territory of Service Locators such as Unity or NInject, which makes me rather uncomfortable. So, I am considering having a set of M-V-VM helper services that optionally plug-into your chosen implementation of a Service Locator (reverse Dependency Injection?).

Forthcoming Additions

In addition to the helper Services, a number of forthcoming features in nRoute will directly help with M-V-VM. Firstly, as described in my earlier post, we'll have strongly-typed INotifyPropertyChanged support using extension methods. Also introduced will be bindable data-triggers for SL, which can be used to trigger either Navigation, ICommands or Actions. And probably something like an Action that yields a response, with the response being consumable in the View. 

In summary, I hope what is observable through the list of features mentioned above, is that nRoute is acutely geared towards realizing M-V-VM type of applications - ensuing a range of benefits probably described elsewhere.

Posted by Rishi on 13-May-09 7:44 AM, 30 Comments