Apr 10 2011

NavigationService in Silverlight gets in the way of Dependency Injection scenarios

Today, I was working on a Windows Phone 7 application, and I really wanted to do things properly, with nice dependency injections in order expose all my dependencies. And by the time I tried to navigate from one page to an other, I realized that the NavigationService in Windows Phone 7 and Silverlight ( as of version 4.0 ) was simply not satisfying.

Why is it so bad ? because, unlike in WPF, there is no way to use the NavigationService to Navigate to an instance of a page : we can only specify an URI to navigate to.
What would that change, one might ask ?
Well, it may seem like nothing to some, but for those out there who are very fond of Dependency Injection (DI) this is really a painful restriction :

let’s see : what can we do by navigating to an instance of a page that we can’t do by just passing the URI to the NavigationService ?

well, for one, we can instantiate the page ourselves and not rely on the NavigationService to instantiate it for us.
If we control the Page creation, we can pass any argument we please to its constructor, Including a view model for instance.

And if we can inject it, we can mock it.
And if we can mock it, we can test the rest of our code properly.

And perhaps most importantly from an architectural point of view, we can clearly communicate the dependencies our page relies on, but more on that later.

I can already hear some people claiming we could always use a view model locator, but in my humble opinion, a view model locator is not a first-class solution to this problem.

The reason why I think so is that using a locator (or an IoC resolution for that matters) to retrieve a resource needed within the class will hide the fact that we are dependent on this resource. If someone forgets to register a view model prior to using it, the application will crash as soon (or as-late, might I say) as it is resolved.
If we use Dependency Injection, we will not even be able to compile the project : if we forget to feed a dependency, that’s how soon the problem should be highlighted, and that’s why it is so important to communicate clearly our dependencies.

… Come on Microsoft, show us some love and give us a decent NavigationService.