In the last MVVM article, I showed how to create a simple MVVM architecture using pure .net and INotifyPropertyChange as a base.

Today I’ll cover converting this project to use a service locator type pattern and an IOC (Inversion of control) container so that we can register our dependencies and inject navigation and dialog interfaces into our view models.

I’ll only cover MVVMLite today but you can alternatively use other MVVM frameworks such as MVVMFresh, MVVMCross or Prism.

I won’t cover how to use this in native Xamarin.iOS or Xamarin.Android frameworks, I’ll only be covering Xamarin.Forms.

I will also assume you know what the MVVM pattern is and how to use it within Xamarin Forms.

So what is MVVMLite?

Simply put MVVMLite is a light weight framework that provides several tools to enable us to create view models faster and easier.

These include:

  • RelayCommands for data bindings
  • Built in messenger (can be used in place of the xamarin messenger service)
  • SImpleIoc – Inversion of control container so we can dependency inject service interfaces into our view models
  • Navigation Service Interface – so we can build our own navigation and call via commands or in the view model
  • Dialog service – We can create custom dialogs that do not need a form instance to be generated
  • plus much more as detailed in the MVVMLite documentation

In this post, I will go through a basic example using data bindings within a login form, using a relay command bound to a button to navigate from a login page to a new info page and how we can do this from the view model.

You will also see how we can dependency inject the navigation interface directly into the view model constructor.

We need to start by created our new project and add the nuget package ‘MVVLiteLibs’ to the project.

Now add our new ViewModels which will inherit from our framework base model (add as plain classes)

In this instance, we do not inherit from INotifyPropertyChange but instead the MVVMLite base class ‘ViewModelBase’ which provides all the functionality that we created using INotifyPropertyChange plus much much more.

public class LoginViewModel : ViewModelBase

 

public class UserInfoViewModel : ViewModelBase

Next, we need to create our two XAML views (LoginView and UserInfoView)

 

public partial class UserInfoView : ContentPage
public partial class LoginView : ContentPage

Now we need to create out Service locator IOC container and register the viewmodels, views and services we have just created.

Let’s call our service locator -> ‘ServiceMdl’ and create the registration code

 

public class ServiceMdl
{     // our nav service
      public mvvmLiteExample.helpers.NavigationService navigationService;
 
      public ServiceMdl()
      {   // instantiate our provider
          ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
 
          // add models and forms here
          this.RegisterIOCServices();
          this.RegisterViews();
          this.RegisterViewModels();
      }
 
      public void RegisterViewModels()
      {
          // reg common view models
          SimpleIoc.Default.Register<LoginViewModel>();
          SimpleIoc.Default.Register<UserInfoViewModel>();
      }
 
      private void RegisterIOCServices()
      {
          // register services here
          navigationService = new mvvmLiteExample.helpers.NavigationService();
          SimpleIoc.Default.Register<INavigationService>(() => navigationService);
      }
 
      private void RegisterViews()
      {
          // views
          navigationService.Configure("UserInfoView", typeof(UserInfoView));
          navigationService.Configure("LoginView", typeof(LoginView));
      }
  }

As you can see here we are basically creating the ioc container and registering all the components within that container.

Now that we have our viewmodels, views and services registered we can start to implement the code in our viewmodels.

Let’s show our new view models and dependency inject the navigation service into our constructors.

 

public class LoginViewModel : ViewModelBase
{
       private INavigationService _nav;
 
       // dependancy injection into the MVVM model.. we can add multiple interfaces in constructuror. 
       // i've added IDialogServce as an example.. 1 or many can be added
       public LoginViewModel(INavigationService navi, IDialogService diag)
       {   // set the dependancy injected navi so we can use it
           _nav = navi;
 
           // setup commands
           this.LoginCommand = new RelayCommand(CheckLogin);
       }
 
       #region name/pass props here
       private string _LoginPassword;
       public string LoginPassword
       {
           get { return _LoginPassword; }
           set
           {   // not how we set our properties here.. this auto calls INotifyProperty change
               Set<string>(ref _LoginPassword, value, "LoginPassword");
           }
       }
 
       private string _LoginName;
       public string LoginName
       {
           get { return _LoginName; }
           set
           {
               Set<string>(ref _LoginName, value, "LoginName");
           }
       }
       #endregion
       #region setup any commands here
       public ICommand LoginCommand { get; private set; }
       private void CheckLogin()
       {
           // do all your login check here
 
           // asume valid so nav to start page
           _nav.NavigateTo("UserInfoView");
           // you can params as well ie. -> _nav.NavigateTo("someformname", _somedataobject);
       } 
       #endregion
   }

Note how we set our properties using the base implementation of inotifypropertychange.

 Set<string>(ref _LoginPassword, value, "LoginPassword");

One area I got queries on in the last MVVM article was that of navigation within the ViewModel.

I’ve added a custom Navigation Helper class which inherited from MVVMLite’s INavigationService interface so we set this up in the service locator code.

The navigation is simple to execute using one of the overloaded methods. We have to use the registered name as per the serviceLocator when we nav to a new view.

 _nav.NavigateTo("UserInfoView");

This will nav to the registered view ‘UserInfoView’.

If you look through the code you won’t see anything that pushes the following into the view model constructor.

public LoginViewModel(INavigationService navi, IDialogService diag)

So how does the constructor in the view model get initiated?

This is called dependency injection and the MVVMLite framework itself injects this from the ioc container via the ‘getInstance’ call on the service locator in the view.

 

Our view could actually stay the same data binding wise with only a simple change needed when the views ‘BindingContext’ is set.

We now bind the view from the service locator instead of creating a new instance and this is the key to injecting the ‘INavgiationService’ into the view model constructor.

     this.BindingContex = (LoginViewModel)ServiceLocator.Current.GetInstance(typeof(LoginViewModel));