Getting started with Hanno.MVVM - Galad/Hanno GitHub Wiki

Welcome to Hanno. In this article you will setup a Windows 8.1 project

First of all, you need to know about Rx, otherwise you won't be able to understand the value of some Hanno features. If you don't, go check out the Rx repository.

Ok now that you are a Rx master, let's get started.

Composition

Hanno does not make any assumption about how you compose your application. We will use Unity as a Dependency Injection container, but you are free to use any container of your choice, and even no container at all. I also suggest to get familiar with the Composition Root pattern if you are not.

We will compose what we need in order to navigate to an empty page, which will have a view model.

Page and view model

The app will have :

  • MainPage.xaml
  • MainPageViewModel

Page name

Hanno refers to pages with their names. Page names are mapped to a page in the composition root. So the first thing to do is to define a constant for the main page name.

public class ApplicationPages
{
    public const string Main = "Main";
}

Registering the view model in the DI container

Since we use Unity, I will register my view model in the container.

container.RegisterType<MainPageViewModel>();

ViewModels inherit from ViewModelBase, which requires an instance of IViewModelServices. You need to either provide an empty implementation, or an instance of ViewModelServices, with all the required services.

This way of working may change in the future.


PageDefinitionRegistry

Let's begin with composing the PageDefinitionRegistry. This class allow to page application pages to be mapped to views and viewmodels.

public void Compose(IUnityContainer container)
{
    container.RegisterType<IPageDefinitionRegistry, PageDefinitionRegistry>(
    				new ContainerControlledLifetimeManager(),
    				new InjectionFactory(unityContainer => RegisterPages(new PageDefinitionRegistry())));
}

private IPageDefinitionRegistry RegisterPages(IPageDefinitionRegistry registry)
{
    return registry.RegisterViewModel<MainViewModel, MainPage>(ApplicationPages.Main);
}

NavigationService

Now we can register the navigation service.

container.RegisterType<NavigationService>(
				new ContainerControlledLifetimeManager(),
				new InjectionFactory(c => new NavigationService(
					Frame.Current,
					c.Resolve<IPageDefinitionRegistry>(),
					new UnityViewModelFactory(c),
					CoreDispatcherScheduler.Current,
					ThreadPoolScheduler.Instance)));
container.RegisterType<INavigationService, NavigationService>(new ContainerControlledLifetimeManager());
container.RegisterType<IRequestNavigation, NavigationService>(new ContainerControlledLifetimeManager());

Some explaination are needed here. The NavigationService class implements 2 interfaces : INavigationService and IRequestNavigation. IRequestNavigation allow us to trigger a navigation to another page and INavigationService handle the navigation state.

**Displaying the first page Now we can display our first page.

In the App.xaml.cs file, go to the OnLaunched method. Some code is already generated. Below the line rootFrame = new Frame(); add the following code :

_unityContainer = new UnityContainer();
var compositionRoot = new CompositionRoot();
compositionRoot.Compose(_unityContainer);

This will register all our services.

Now look a little bit below for a code looking like :

if (!rootFrame.Navigate(typeof(MainPage), e.Arguments)) 
{
    throw new Exception("Failed to create initial page"); 
} 

And replace it with :

var nav = _unityContainer.Resolve<IRequestNavigation>();
nav.Navigate(CancellationToken.None, ApplicationPages.Main);

Start the app, and observe that the first page is displayed.