views:

812

answers:

4

I'm hitting paralysis by analysis I think...

Which should I go for for my first IOC container: Autofac or Ninject?

(Just want an open source, nice and simple, IOC container)

+8  A: 

Just want an open source, nice and simple, IOC container

Then Ninject should be your choice, it is very, very, VERY simple and nice. Also it has a very funny documentation =)

Restuta
thanks Restuta - have you used Autofac too out of curiosity? i.e. just wondering if your recommendation is just based on knowledge of Ninject or of both?
Greg
I know Ninject, Autofac, Unity and Castle Windsor, so I can say that Ninject is totally the simpliest.
Restuta
ok - Ninject is the way then :) Thanks all
Greg
+1  A: 

I use Ninject. With Ninject2 the syntax is even more concise and easier to use. There are integrations with a ton of other projects inherently (like Common Service Locator) or externally through the Ninject.Extensions series of projects by Ian Davis.

Autofac looks very cool and is apparently fast but the syntax is fairly complicated and there is a steeper learning curve.

Jeffrey Cameron
thanks Jeffrey - so Ninject might be the way to go, mainly based on syntax then? or are there non-syntax reasons why it's simpler?
Greg
A bit of both. I find the Ninject syntax reads naturally. Autofac has a lot of high-falutin' terminology about inner containers, factory methods etc. These might be needed in some circumstances, but I have yet to encounter one of them! For beginners, Dependency Injection concepts are hard enough to grasp without throwing a bowl of terminology soup at them.
Jeffrey Cameron
The comment on terminology is relevant to Autofac 1. Comparing Autofac *2* and Ninject 2, they have a very similar set of terms. Autofac 2 does "automatically" a lot of the things that Autofac 1 required explicit configuration for.
Nicholas Blumhardt
If this is true I will have to check it out myself. I read The Relationship Zoo and Sam's comments above with great interest!
Jeffrey Cameron
+11  A: 

Autofac 2!

Autofac 2 will enforce better design by not (by default) performing automatic self-binding for concrete types.

Autofac 2 has auto-generated factories (if a registration is added for IAmAnInterface, you can request Func<IAmAnInterface> to get a factory object, without ever explicitly registering Func<IAmAnInterface>.

With its awesome registration syntax, you can harness the power of Ninject Providers with inline code written right into your configuration classes/modules.

Autofac 2 actually supports more higher-order dependencies than just Func<>. Check out The Relationship Zoo for more automatically resolved types you can request.

The learning curve of Autofac 2 is a little higher (I'm still pretty new), but if you already understand proper dependency injection (and aren't planning on using a container just for service location), then it is worth learning. You can create your own convention-based resolution rules with Autofac in very few lines of code. For example, the following 7 lines of code set up all my presenters and command executors:

        builder.RegisterAssemblyTypes(typeof(IPresenter).Assembly)
               .Where(t => t.IsAssignableTo<IPresenter>())
               .OnActivating(e => ((IPresenter)e.Instance).SetupView());

        builder.RegisterAssemblyTypes(typeof(IExecutor<>).Assembly)
               .Where(t => t.Closes(typeof(IExecutor<>)))
               .AsClosedTypesOf(typeof(IExecutor<>));

Admittedly, IsAssignableTo and Closes are extension methods, but still, you get the idea.

I haven't used Ninject 2 since it was in beta, so it may have more features that compete well with Autofac's power; nevertheless, my recommendation stays the same. Automatic resolution of higher-order dependencies is really, really radtastic-optimus-prime-atron.

Sam Pearson
In the most recent builds (almost at RTM!) you can simply say .AssignableTo<IPresenter>(), and AsClosedTypesOf() no longer requires an additional Where() clause either :) ... Thanks for the great write-up Sam!
Nicholas Blumhardt
I primarily use Ninject now though I have used Autofac as well -- both fantastic IMO, but you get a +1 solely for the use of "radtastic-optimus-prime-atron" in an answer.
Peter Meyer
+6  A: 

I suppose I'm biased, but I would go with Ninject. How can you not love any library that has a name and all of its documentation based around ninjas?

It's somewhat of a style issue, but to me, AutoFac has always felt "backward" with this syntax:

builder.RegisterType<Foo>().As<IFoo>();

In other words, first you specify the concrete implementation and then bind it to the interface you want to support. The question you usually want answered, though, is for a given interface, which concrete type is the implementation? AutoFac's syntax makes it a little more difficult to visually scan the list and answer this question than Ninject, which goes like:

Bind<IFoo>().To<Foo>();

It's a little bit shorter, and it puts the abstract type first, which means you can easily look at a module and answer the question which concrete type is bound to the abstract type IFoo?

But again, a lot of it factors into personal preference. They're both good, solid libraries that will do pretty much everything you need them to do.

Supported platforms also factor into the decision: Ninject 2.0 runs on Mono and .NET Compact, which Autofac doesn't claim to support. On the other hand, Ninject needs version 3.5 of the .NET Framework to run, whereas Autofac can still run on the 2.0 Framework. So it's possible that your particular environment might force your hand; otherwise, try both and see which one works better for you. They're both very easy to get up and running.

Aaronaught
Curious as to why NInject would require 3.5. After all it is the same clr as 2.0...
Peter Lillevold
@Peter Lillevold: According to the author, it's because Ninject 2.0 relies on Linq. http://wiki.github.com/enkari/ninject/changes-in-ninject-2
Aaronaught
Personally I prefer Autofac - but I completely agree that the Ninject syntax in this case is much clearer.
UpTheCreek
The Autofac syntax is in reverse because Autofac supports multiple services on the same component, e.g. RegisterType<Foo>().As<IBar>().As<IBaz>(). Note also that RegisterType<Foo>() is more succinct than Bind<Foo>().ToSelf() :)
Nicholas Blumhardt