Quantcast
Channel: Codenutz - all about how to make an app » Intermediate
Viewing all articles
Browse latest Browse all 5

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

$
0
0

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:

resolverContainer.Register<MainViewModel>(r => new MainViewModel(r.Resolve<IDevice>()));

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:

Install-Package XLabs.IoC.Autofac

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

Install-Package XLabs.IoC.Autofac -ProjectName Codenutz.XFLabs.Basics.Droid

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:

private void SetIoc()
{
    var containerBuilder = new Autofac.ContainerBuilder();

    containerBuilder.Register(c => AndroidDevice.CurrentDevice).As<IDevice>();
    containerBuilder.RegisterType<MainViewModel>().AsSelf();

    Resolver.SetResolver(new AutofacResolver(containerBuilder.Build()));
}

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:

Install-Package XLabs.IoC.Ninject

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

Install-Package XLabs.IoC.Ninject -ProjectName Codenutz.XFLabs.Basics.Droid

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:

private void SetIoc()
{
    var standardKernel = new StandardKernel();
    var resolverContainer = new NinjectContainer(standardKernel);

    standardKernel.Bind<IDevice>().ToConstant(AndroidDevice.CurrentDevice);

    Resolver.SetResolver(resolverContainer.GetResolver());
}

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:

Install-Package XLabs.IoC.TinyIoC

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

Install-Package XLabs.IoC.TinyIoC -ProjectName Codenutz.XFLabs.Basics.Droid

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:

private void SetIoc()
{
    var container = TinyIoCContainer.Current;

    container.Register<IDevice>(AndroidDevice.CurrentDevice);

    Resolver.SetResolver(new XLabs.Ioc.TinyIoC.TinyResolver(container));
}

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:

Install-Package XLabs.IoC.Unity

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

Install-Package XLabs.IoC.Unity -ProjectName Codenutz.XFLabs.Basics.Droid

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:

private void SetIoc()
{
    var container = new UnityContainer();

    container.RegisterInstance<IDevice>(AndroidDevice.CurrentDevice);

    Resolver.SetResolver(new XLabs.Ioc.Unity.UnityResolver(container));
}

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.

The post Autofac, Ninject, TinyIoc & Unity with Xamarin Forms Labs (XLabs) appeared first on Codenutz - all about how to make an app.


Viewing all articles
Browse latest Browse all 5

Latest Images

Trending Articles





Latest Images