In this post, I want to describe how the Navigation Service works and how it relates to the all important INavigationHandler. To be honest, the Navigation Service is a very thin wrapper around the Routing Service; but it is semantically very important because it puts a context around the consumption of the routing responses - for navigation purposes obviously. I'll take on each part related to the Navigation functionality in a piece by piece manner, but first below is what I consider my mind-map relating to Navigation and Routing in nRoute:

Click for a Larger Picture

Navigation Requests

Basically all requests constitute of two principle things, one the Url and two a name-value collection; and this is accordingly reflected in the IUrlRequest interface. The other member in that interface is the ServiceState property, which is supposed to be for internal use of the services to carry any service-specific data. 
NavigationRequests
Now, the only thing that the NavigationRequest type adds is the the NavigationMode property, which is an enumeration that tells the container what kind of request (back, forward etc) we are dealing with - it's usage is container specific and some containers totally ignore it. However, I made it a first level concept to enabled browser integration and minimize ambiguity. All the same, for most purposes you will only need to be concerned with the the Url alone. In fact I suggest that you should try and minimize the need for passing name-value parameters, and consider using defaults parameters if necessary. One other point, the Url that you register or use should not contain a "?" and it should not start with either "/" or "~" (these are trimmed on use, but avoid them), I've carried these requirements intact from asp.net routing specifications as it made the relative Urls sort of consistent.

Navigation Response

The navigation response is based on the IUrlResponse interface, that defines five almost self-describing properties. The important ones are Content, which holds the actual result. And the other is ResponseParameters, which is basically a merged name-value collection of the original request parameters, the default parameters set while defining the route, and the parsed token-parameters from the Url. And priority level for merging is such that request parameters override Url parsed parameters, which in turn override the default parameters.
NavigationResponses 
The navigation response adds one things, which is the NavigationStateManager property of type ISupportNavigationState interface. The ISupportNavigationState is a mechanism to participate in state management but participation is optional, and also the reason it is separated from the actual result is to facilitate M-V-VM like pattern. So for example, the response itself can be an Usercontrol, but it doesn't have to implement the state management, whereas it's ViewModel can do that or a parent controller can do that. One last thing, the Error property only holds exceptions that are occur in the course of getting the actual response (from the IRouteHandler) and not say from an invalid Url.

IRouteHandler Implementations

You can think of the IRouteHandler as the your end of the bargain, that when posed the Url-specific request provides the response - which is basically the same in asp.net routing or MVC.  Now you can create your own handlers very easily, but I provide two build-in implementations - one specializes in loading assembly-embedded resources like images, xaml-only files, text files etc. The other, more general purpose one, takes in two delegates yielding the response and optionally an ISupportNavigationState object.   

// NavigationRouteHandler Constructor
public NavigationRouteHandler(Func<ParametersDictionary, Object> responseResolver,
           Func<Object, ISupportNavigationState> navigationStateManagerResolver) { ... }

In the first parameter of the constructor signature above, we pass into the Func the request's name-value collection and it is supposed to return the result, which we then pass into the second Func to get the state management related interface. However, like I said before, the second parameter to resolve the state is optional. Let me stress this again, you can provide your own implementation as per your needs, say for example a handler that dynamically downloads assemblies on demand.  

INavigationHandlerINavigationHandlerInterface

The INavigationHandler Interface is a very simple interface, almost ICommands'que. The ValidateRequest is asked as to if the handler can process the request, if false it yields a NavigationResponse will null content and Cancelled status. The ProccessResponse, is equally simple in that it is asked to process the response. Now, the inbuilt navigation containers all use this to get the response and display it, but if you were devious enough you will know that it doesn't have to be that. You could for example use this as a signalling mechanism or even get data - and you can get even more creative if used with navigation behaviours I mentioned in my last post. However, you must be careful because the calls to the handler are all synchronous, which means you can potentially block the UI thread inappropriately.

Navigation ServiceNavigationServiceClass

Like I said earlier the Navigation Service is a wrapper around the Routing Services, but it importantly provides the capability to inject responses into through the INavigationHandler interface. And it does use that mechanism, when you use the Navigate method that takes in a NavigationRequest and an INavigationHandler - to which it will given back the response to process. The other main method is Resolve, which takes in a NavigationRequest and gives out a NavigationResponse. That is important in a way, because it means you can get the response from without having to go through a handler. So you have two ways to get the response, but you will almost always use the Navigate method which in a manner of speaking injects the response into the passed in INavigationHandler container.

The MapRoute method provides a couple of different ways to register a Navigation Route, some of which I shown before. However, truth be told, in as far as registering routes you can totally forgo the NavigationService and register against either the RouteTable or the RoutingService itself. Lastly, the MapLoadedAssemblieRoutes and MapAssemblyRoutes methods provide support for mapping Url to content using attributes. MapLoadedAssembliesRoutes enlists all loaded assemblies and passes them to the MapAssemblyRoutes method which auto-registers navigation routes - as described next.

Attributes Mapping

In a lot of use-cases the "strong-by-convention" way of registering routes can frankly be burdensome, so I created an extensible AOPish way to auto-register Url and it's required IRouteHandler.

  MapNavigationAttributes

The shown MapNavigationBaseAttribute is the attribute the NavigationService looks for when asked to map an assembly, and then to register the navigation route it calls upon the attribute's ResolveHandler abstract method. That is very simple, but what this also means is you can create your own derived attributes to suit your loading strategy, say one that uses some kind of dependency injection tool. And the other obviously useful thing about attributes is that it is registered at runtime, so you can say load in a different assemblies on a per user basis (like don't load Admin related assemblies when the user is a not an Admin). I'll also show in another post a derived attribute that does M-V-VM automagically for you.

That's it for now, these posts are really getting long and dry - but the drudgery is necessary because these are meant to be persudo documentation for nRoute. Anyhow, I hope you have learned how the whole request in and response out thing works. I'll leave you with some immortal words from Karate Kid:

Daniel LaRusso: Hey, what kind of belt do you have?
Mr. Kesuke Miyagi: Canvas. J.C. Penny. Three ninety-eight. You like.
Daniel LaRusso: No, I meant...
Mr. Kesuke Miyagi: In Okinawa, belt mean no need rope to hold up pants.

Comments

trackback
Ork Pad
on 17-Mar-09 11:48 AM
Trackback from Ork Pad

nRoute Actions: Lights, Camera, Silverlight

trackback
geff zhang
on 10-Jun-09 8:20 PM
Trackback from geff zhang

?? nRoute ??????? Silverlight ?????

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading