Nate Kohari informed me that he fixed the performance issue that I discovered in my last test, so I thought I rerun the benchmark against the trunk version (revision 62) of Ninject.

I have also included another new container named Autofac, written by Nicholas Blumhardt and Rinat Abdullin.

This container has nice list of features, here are a few:

  • Autowiring (with out any intrusive attributes)
  • XML Configuration Support
  • Nice C# registration API (including possibility to create components with expressions)
  • Module system (nice way to structure parts of your application)
  • Nested containers

The registration API is at first glance like any other IoC container except it also provides the ability to override the autowiring by defining how components are created by using lambda expressions. Here is an example:

// using autowiring
builder.Register<UserController>().FactoryScoped();
// using expressions
builder.Register(c => new UserController(c.Resolve<IUserRepository>(), c.Resolve<IAuthentificationService>()))
  .FactoryScoped();

The second method could potentially be a lot faster since in it you create a anonymous method that creates the object directly. There is a lot more code to write and if you change the constructor you need to update the registration code, so I am not sure you would want to use it to for most components. To be fair to the other containers in the test I tested Autofac with both autowiring registration and with expression based registration. For more detail on how the benchmark works please view the first benchmark post.

Another interesting feature of Autofac is it's support for nested containers with predicable component cleanup. 

var container = // ...
using (var context = container.CreateInnerContainer())
{
  var controller = context.Resolve<IController>();
  controller.Execute(); // use controller..
}

In the above example the controller and all it's dependencies that implements IDisposable will be disposed.

Here are the results:

IoCSingleton_Autofac

IoCTransient_Autofac

It is nice to see that the Ninject problem has been solved. When using Autofacs expression (lambda) based registration API the results are, not surprising, a lot quicker than the other containers. I would have almost through that the performance difference was going be bigger, seeing how fast the new operator was in my first benchmark (where I made a crude comparison with using the new operator directly to create all the instances).  

My conclusion is the same as after the first test, the performance difference is not significant to warrant consideration when choosing a IoC container. Unless you create a incredibly large amount of transient components (not recommended), then maybe use Autofac :)

It was fun to try out Autofac, it is looking like an interesting contender, and might even replace Castle Windsor as my favorite. I doubt it though, Castle Windsor probably has the largest user base and I am pretty familiar with it's codebase / extension points. But who knows, you shouldn't always stick to what you know :)

For the benchmark code: IoCBenchmark_ReRevisted.zip