Configuration Comparison of Dependency Injection Containers (IOC)

I have often questioned myself which IoC container would be suitable for this or that project best. Their performance is only one side of the coin. The other side of the coin is the simplicity and speed of learning. So, I decided to compare the following containers from this point of view: Autofac, Simple Injector, StructureMap, Ninject, Unity, and Castle Windsor. In my opinion, these are the most popular IoC containers. You can find some of them in the list of the top 20 NuGet IoC packages. Also, I added a few containers based on my personal preferences. I really like Autofac and when writing this article I was reinforced in my choice in most of the cases.

In this article, I will describe the basics of the IoC containers, such as configuration and logging of components. I also want to compare the management of lifetime scope and advanced features. Code examples can be found in the LifetimeScopesExamples GitHub repository.

Documentation

When writing this article, I needed to refer to the documentation of certain IoCs. Unfortunately, not every IoC container has a good description and I had to google for a solution. I made up the following table with the summary of my searches.

 QualityComment
AutofacSuperbDocumentation contains the whole nine yards. I didn’t have to google anything. Examples are clear and useful.
Simple InjectorGoodDocumentation is similar to the previous one, but looks a bit raw. I had to google certain aspects, but I quickly found a solution.
Structure MapAverageNot all cases are described in the documentation. Descriptions of such things, as registration with expression, property and method injections are bad. Googling was necessary.
NinjectIt existsNot all cases are described. Descriptions of such things, as registration with expression, property and method injections are bad. Googling was necessary. Finding of solutions was hard.
UnityBadIn spite of the text volume, the documentation was useless, since It was hard to work through longread pages. All cases had to be googled, and it was hard to find them.
Castle WindsorAverageNot all cases are described, or there are unclear examples. Googling was necessary.

You can chase up my words – here are links to the documentation files:

Configuration

In this article, I do not consider the XML configuration. All examples describe the frequent cases of configuring IoC containers through their interface. Here, you will find the following:

  • Constructor injection.
  • Property injection.
  • Method injections.
  • Expression logging – allows specifying additional creation logic.
  • Conventional logging – allows logging everything automatically.
  • Module logging – allows specifying a class that encapsulates configuration.

The purpose of the article is to provide working examples for each of the cases. Such complex scenarios as parameterized loggings are beyond the scope of this article.

Object model and test scenario model

I created a simple model for checking the IoC containers. There are several modifications of it to use the property and method injections. Some of the IoC containers require usage of special attributes for initializing through properties or methods. I described it explicitly in each section.

The test script creates a container and retrieves an object from it twice to view how their timelife scope management works.

Constructor Injection

In its basic version, the configuration does not require any special attributes or names.

Autofac

Simple Injector

StructureMap

Ninject

Unity

Castle Windsor

Property Injection

Some IoC containers require the use of special attributes that help to identify properties for initialization. Personally, I do not like the approach since the object model and IoC container become strongly related. Ninject requires the usage of the [Inject] attribute, Unity requires the [Dependency] attribute. At the same time, Castle Windsor does not require anything to initialize properties, since it happens by default.

Autofac

Simple Injector

StructureMap

Ninject

Unity

Castle Windsor

Method Injection

Similar to the previous method, this approach can help with circular references. From the other side, it creates the situation we need to avoid. In a few words, the API does not give any hint that such initialization is required to fully create an object. Here you can read more about temporal coupling.

Also, some IoC containers require the use of special attributes with the same cons. Ninject requires the [Inject] attribute for methods. Unity requires the usage of the [InjectionMethod] attribute.

All methods marked with such attributes will be executed when the object is created by the container.

Autofac

Simple Injector

StructureMap

Ninject

Unity

Castle Windsor

Expression Logging

Most of the cases in previous sections represent logging with lambda expressions or delegates. This way of logging method helps to add some logic at the moment of object creation, but it is not a dynamic approach. For dynamics, parameterized logging is the best choice that allows creating various implementations of the same components in the run-time.

Autofac

Simple Injector

StructureMap

Ninject

or

Unity

Castle Windsor

Ninject has differences between configuration with ToMethod and ToConstructor. In short, when you use ToContructor, you can also use conditions. The following configuration won’t work for ToMethod.

Conventional Logging

In some cases, you don’t need to write configuration code at all. The general scenario looks in the following way: scanning assembly to find the required types, extraction of their interfaces and logging them in a container as the intreface-implementation pair. This may be useful for very large projects but can be hard for a developer who is unfamiliar with the project.

Autofac logs all possible implementations and saves them in an internal array. According to the documentation, it will use the last variant for resolving by default. Simple Injector does not have ready methods for automatic logging. Yo need to make it manually (an example is provided below). StructureMap and Unity require public implementation classes since their scanners are not visible to others. Ninject requires an additional NuGet package, Ninject.Extensions.Conventions. Also, it requires public implementation classes as well.

Autofac

Simple Injector

StructureMap

Ninject

Unity

Castle Windsor

Module Logging

Modules can help you to divide your configuration. You can group them by context (data access, business objects) or by purpose (production, test). Some of the IoC containers can scan assemblies in the search for their own modules.

Autofac

Simple Injector
StructureMap
Ninject
Unity
Castle Windsor