Using a Dependency Injection Container in Xamarin Forms Labs

0 Flares Twitter 0 Facebook 0 StumbleUpon 0 Google+ 0 LinkedIn 0 0 Flares ×

Xamarin Forms Labs - Dependency Injection

Using a dependency injection (DI) container in your Xamarin Forms app can make developing it a lot smoother and your code a lot cleaner. Inversion of control (IOC) is integral (in one form or another) to Xamarin Forms and Xamarin Forms Labs, so implementing it in a standard and recognised ways is a huge benefit.

In this article I’m going to show you how to use a dependency injection container in your app, by building on “Getting Started with Xamarin Forms Labs“, demonstrating a basic usage. I’ll follow this article with several other articles that show how to hook up various DI containers that are supported by Xamarin Forms Labs.

I apologies for the amount of acronyms used in this article! I do my best to keep it to a minimum but this area is riddled with them!

The full sample projects are available on GitHub.

DI Containers and Xamarin Forms Labs

Over the last few years dependency injection containers have become a standard part of most projects, and for good reason. Whilst they can be complicated to manage at first, they can simplify the creating and management of dependencies tremendously. Anyway, I don’t want to get into the DI container debate!

The first thing to understand is that IOC is integral to any Xamarin Forms app. Anywhere that you’re using the Xamarin Forms DependencyService, you’re effectively leveraging an in-built service locator – which is an IOC pattern. Generally speaking DI has become the preferred pattern for IOC, as it requires that all components within your app make it very clear what dependencies they have.

Xamarin Forms Labs has DI throughout its MVVM framework, so it makes sense to make use of it. We actually hooked up the most basic DI container in getting started with xamarin forms labs – the SimpleContainer. In fact the ViewFactory makes use of the underlying container to register its views and viewmodels ViewFactory.Register<MainView,MainViewModel>(); and then create the pages ViewFactory.CreatePage<MainViewModel>().

Abstracting away the DI container with the Resolver

One thing that’s really important to understand is that Xamarin Forms Labs abstracts away the underlying DI container, so the interface is the same when using that container in your main project, regardless of which container you’re using.

The interface is represented by the static Resolver class, which you should recognise from the previous tutorial with the lines:

These lines create a new SimpleContainer, and assign it as the resolver for the project. This means that the SimpleContainer is used to resolve all dependencies throughout the project.

What this means is that outside of your dependency registration code, you should never refer to the SimpleContainer directly. Primarily you should resolve all dependencies using either Resolver.Resolve, or get a reference to the IDependencyContainer (which we’ll come to later).

Using the SimpleContainer

The most basic dependency injection container is the SimpleContainer, which is fine in a lot of cases. As previously mentioned the last article showed how to create the SimpleContainer and assign it as the Resolver in the SetIoc method (which appeared in all 3 projects – Android, iOS and Windows). The code in SetIoc was completely the same in all 3 projects, with the exception of a couple of extra lines in the Windows Phone project:

You may ask why we write the same code for all 3 environments – the answer is that when we come to set-up our container, most of the dependencies will be different for each project. Those dependencies that are the same can be registered in the main app project separately.

Displaying device information

Understanding IDevice

In order to work through an example, I’m going to add something about the device to the message on our previous examples ViewModel. To do this I’ll need access some device specific information, which I can get at using the Xamarin Forms Labs Device object.

Xamarin Forms Labs provides a convenient Device object for each environment represented by AppleDevice.CurrentDevice, AndroidDevice.CurrentDevice and WindowsPhoneDevice.CurrentDevice. Each of these implement the common IDevice interface, but the implementation is within the device specific library.

For example whilst IDevice is in the XLabs.Platform assembly that is shared across all projects, AndroidDevice.CurrentDevice is in the XLabs.Current.Droid assembly, that is only used by the Android project. And this is where IOC and DI come in!

Using IDevice using Dependency Injection

So to get access to the current platforms device object, we must register it in each project and inject it using our DI container.

  1. To registering the IDevice using the SimpleContainer we amend the SetIoc method in each project by adding the following line immediately after creating the container:

    • Android: resolverContainer.Register<IDevice>(r => AndroidDevice.CurrentDevice);
    • iOS: resolverContainer.Register<IDevice>(r => AppleDevice.CurrentDevice);
    • WinPhone: resolverContainer.Register<IDevice>(r => WindowsPhoneDevice.CurrentDevice);
    • The SetIoc should look something like this:

  2. Next we add a constructor parameter to the MainViewModel so it can access the device information:

    • Add a constructor parameter for IDevice
    • Assign that parameter to a private member variable
    • Amend the message to include some device related information
    • The MainViewModel should look something like this

Most DI containers support automatic dependency injection, where the container will automatically attempt to resolve any constructor arguments it knows about. The SimpleContainer doesn’t do this because…well…its simple! So we have to explicitly tell the container how to create the view model.

The simplest way to achieve this is in our SetIoc method. In each platforms SetIoc, immediately after out previous registration we add resolverContainer.Register<MainViewModel>(r => new MainViewModel(r.Resolve<IDevice>()));. The full method should look something like this:

This registration registers the MainViewModel in the container and also uses a lambda expression to tell the container how to construct it (i.e. by resolving the IDevice as the first constructor argument). Once this is complete in each project you should be good to go and you should see something like this:

Genymotion emulator with IDevice dependency working

Wrapping up

The truth is that a lot of the benefit you get from a DI container is the automatic dependency injection, so the SimpleContainer isn’t helping us out as much as we’d like. That said getting up and running with the SimpleContainer is quick, lightweight and simple – so its generally where I start when firing up a new Xamarin Forms project.

In my next post I’ll show you how to hook up some other DI containers such as Ninject and Autofac. These containers offer more features and therefore greater benefit.

Are you using DI in your apps? Which container are you using, if any?

The full sample projects are available on GitHub.

, ,

The Essential App Marketing Kit
Subscribe To My Newsletter To Get an Entire Chapter From The Book for FREE
Never display this again
0 Flares Twitter 0 Facebook 0 StumbleUpon 0 Google+ 0 LinkedIn 0 0 Flares ×