Autofac, Ninject, TinyIoc & Unity with Xamarin Forms Labs (XLabs)

22 Flares Twitter 0 Facebook 0 StumbleUpon 6 Google+ 4 LinkedIn 12 22 Flares ×

Xamarin Forms Labs Dependency Injection Containers

Autofac, Ninject, TinyIoC & Unity are 4 widely used dependency injection containers that can be used with Xamarin Forms Labs. This post is going to quickly run over how to get started with each of them.

In my previous post about dependency injection in Xamarin Forms Labs (XLabs) I covered the basics of using the in-built SimpleContainer in Xamarin Forms Labs as your dependency injection container.

As pointed out by Sami Kallio in this LinkedIn discussion, the SimpleContainer is probably good enough to be used on projects of any size – its simple, lightweight and gets the job done. It also means you have less components in your project which can’t be a bad thing for file size and complexity.

The full sample projects are available on GitHub.

TL;DR

Short version – to get started with Autofac, Ninject, TinyIoC or Unity with Xamarin Forms Labs jump to the section with one of these links:

Why bother with a different DI container?

You definitely shouldn’t feel you have to use a different DI container just because you can, but there are a few reasons why you might want to.

Primarily the other DI containers all have larger feature sets than the SimpleContainer. For example, as we saw in the previous article you have to tell the SimpleContainer how to resolve all the dependencies:

Its not a massive pain, but it would be much easier if the DI container could look at the arguments needed to construct MainViewModel, and resolve them automatically. This feature is called automatic injection (or automatic dependency injection) and is supported by all of the containers that we’re covering in this article.

There are numerous other features that are supported by the different DI containers such as convention based registration, registration from settings, interception and more. Each different container supports a different set of features so its worth looking into this a little bit.

One word of caution though – some features (interception springs to mind) probably wont work in the Xamarin world as there are restrictions on dynamic code generation – so don’t assume that just because the container has support for it that you can use it.

The last reason I can see to use a more widely available DI container is familiarity. You may have use Autofac or Ninject on a previous project, or in your web project so sticking with the same container seems to make sense.

What we’re trying to do

Given that there’s a multitude of containers that all support different features, what are we trying to achieve? Personally, for mobile projects I prefer to keep things pretty simple and will either choose to stick with SimpleContainer or use a container primarily for automatic injection. I generally like to wire up all my component registrations manually as I like to be explicit about these things.

So I’m just installing the DI container, replacing the SimpleContainer implementation and making sure everything continues to work as expected! In each of the examples below I’m only going to show the Android implementation as the code for Windows Phone and iOS is almost identical and it’s simple to see what you need to change. The full sample projects on github have the full code for every platform.

In each case, the same changes need to be applied to the iOS and Windows Phone projects, except change the AndroidDevice bit to either AppleDevice or WindowsPhoneDevice. Also the WindwsPhone SetIoc method will also need to keep the part about var app = new XFormsAppWP(); and app.Init(this);

Each example really only has 2 steps:

  1. Install the NuGet package (every one has its own NugGet package)
  2. Hook up the container

Autofac & Xamarin Forms Labs

The Autofac package is called XLabs.IoC.Autofac and needs to be installed on all platform specific projects. You can do this with either the package manager or by executing the following in the package manager console for each project:

You can use the ProjectName flag to specify the project to install to:

This will download all the dependencies and get everything installed to where you need. We then need to change our SetIoc method to look something more like this:

You’ll need to make sure you have using XLabs.Ioc.Autofac; at the top of your class.

The syntax is very similar to the SimpleContainer, except when we register the view model we don’t have to specify the constructor expression. I actually think we shouldn’t have to register the view model at all, as the act of registering it with the ViewFactory should be enough, but I think there’s a bug in the current XLabs package.

Ninject & Xamarin Forms Labs

The Ninject package is called XLabs.IoC.Ninject and needs to be installed on all platform specific projects. You can do this with either the package manager or by executing the following in the package manager console for each project:

You can use the ProjectName flag to specify the project to install to:

You’ll need to make sure you have using XLabs.Ioc.Ninject; at the top of your class.

This will download all the dependencies and get everything installed to where you need. We then need to change our SetIoc method to look something more like this:

The syntax is quite different for Ninject as it uses Bind and To, but the concepts are pretty similar. We don’t have to register the view model at all, as the act of registering it with the ViewFactory is enough, given that Ninject can automatically resolve the constructor arguments.

TinyIoC & Xamarin Forms Labs

The TinyIoC package is called XLabs.IoC.TinyIoC and needs to be installed on all platform specific projects. You can do this with either the package manager or by executing the following in the package manager console for each project:

You can use the ProjectName flag to specify the project to install to:

You’ll need to make sure you have using XLabs.Ioc.TinyIoC; at the top of your class.

This will download all the dependencies and get everything installed to where you need. We then need to change our SetIoc method to look something more like this:

The syntax is quite similar to the SimpleContainer for TinyIoC. We again don’t have to register the view model at all, as the act of registering it with the ViewFactory is enough, given that TinyIoC can automatically resolve the constructor arguments.

Unity & Xamarin Forms Labs

The Unity package is called XLabs.IoC.Unity and needs to be installed on all platform specific projects. You can do this with either the package manager or by executing the following in the package manager console for each project:

You can use the ProjectName flag to specify the project to install to:

You’ll need to make sure you have using XLabs.Ioc.Unity; at the top of your class.

This will download all the dependencies and get everything installed to where you need. We then need to change our SetIoc method to look something more like this:

The syntax is quite similar to the SimpleContainer for Unity. We again don’t have to register the view model at all, as the act of registering it with the ViewFactory is enough, given that Unity can automatically resolve the constructor arguments.

Wrapping up

Hopefully this should give you everything you need to get up and running with the IoC container of your choice. There are other popular containers such as Castle.Windsor that aren’t currently supported in Xamarin. This is largely because of the way in which they’re currently implemented and the lack of an available portable class library project.

That said there’s plenty of choice, and in my opinion you really don’t need a complicated, feature rich container for mobile projects. My personal choice would be either stick with the SimpleContainer, or something like Ninject (because its got ninjas in the documentation)!

What’s you preferred dependency injection container and why? Or do you prefer to handle it all manually?

The full sample projects are available on GitHub.

, ,

  • Hi Matt,

    personally I’m using Autofac because I love its clean FluentAPI and its flexibility, and, what’s most important in mobile development, it has a very small memory footprint.

    I have one question though: Your example shows how to register platform-specific services in the various platform projects. But I have also platform-agnostic services which reside in the core project and which of course also need to be registered with the Autofac container.

    How would you deal with that situation?

    Regards
    Thomas

    • Hey Thomas

      I haven’t actually got the code in front of me right now but I think one way to do this is to register the container itself (using the IDependencyContainer interface). So for example with Ninject it would look something like this:

      standardKernel.Bind().ToConstant(resolverContainer);

      Then in your App.cs you can access the container via the dependency resolver and register things there.

      I cant remember exactly but I’ll try to get a post up about it with a working example

      • Sami Kallio

        Yes, that would work if you needed to register something outside the main IOC setup. I personally prefer to register all on the same method as it has better maintainability and is overall cleaner. Shared project becomes handy if you need to register many PCL implementations. The platform specific stuff is easily handled by compiler directives:

        #if __IOS__
        using PlatformDevice = XLabs.Platform.Device.AppleDevice;
        using SQLitePlatform = SQLite.Net.Platform.XamarinIOS.SQLitePlatformIOS;
        #elif __ANDROID__
        using PlatformDevice = XLabs.Platform.Device.AndroidDevice;
        using SQLitePlatform = SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid;
        #else
        using PlatformDevice = XLabs.Platform.Device.WindowsPhoneDevice;
        using SQLitePlatform = SQLite.Net.Platform.WindowsPhone8.SQLitePlatformWP8;
        #endif

        .Register(t => PlatformDevice).Register

  • Sami Kallio

    Matt, for AutoFac you can try to update the NuGet package to their prerelease version to see if the problem goes away. I had the pre-release references in unit tests and it fixed some of the issues but for XLabs release I put the released version back in. If they every upgrade the pre-release to released state I will modify the dependency but for now I probably wouldn’t use Autofac.

    There are some unit tests available in the source (the unit test solution is a bit outdated) that goes through some of the features to see which platform supports what: https://github.com/XLabs/Xamarin-Forms-Labs/tree/master/UnitTesting/IocTests

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