One more interesting and fresh .NET IoC container: autofac

Thursday, January 10th, 2008 | Articles

Recently I’ve stumbled upon the autofac IoC container.

This container creates an impression of being more flexible and lean than the Castle, StructureMap, and the ObjectBuilder. Additionally, it is supposed to provide inherently good performance, scope and disposal handling.

Well, if the container uses lambda expressions as one of the options to register components, that already tells something about the approach (yes, this means “no Constructor reflection”). If everything is at this level then theoretically we could be talking about cheap and numerous MicroScopes here.

Given that, the autofac could be a better alternative for the Castle in xLim 2 solution.

One usability problem for xLim 2 lies within the .NET framework incompatibility. xLim 2 itself is restricted  to 2.0 for a number of reasons; autofac uses 3.5 and VS 2008.

This turned out to be just a small obstacle. In my last post I’ve spoken about using .NET 3.5 features for the .NET 2.0. With that, it took only 10 minutes to compile the sources against .NET 2.0. I’ve simply copied a big chunk of the “System.Linq.Enumerator, System.Core.dll” extension class into the solution. It compiled and passed all the tests flawlessly.

However it took a little bit more time than that to start playing with the container (it is curious that the biggest efficiency drain during these 90 minutes was the absence of the Resharper in the fresh install of VS 2008).

I’ve prototyped a couple of primary usage scenarios and the first impression is that autofac is capable of handling the xLim 2 better than the Castle MicroKernel/Windsor Container currently does (of course there should be more solid testing before the actual replacement would be seriously considered).

The strongest argument against the autofak is that it does not have solid community around it and thus there is no solid production background. In fact, it is being developed right now by Nicholas Blumhardt. However the last point does have some appeal to it, since small systems/groups always seem to have more flexibility and mobility (that’s due to lower inertia and decision-making lags).

Additionally I was not able to get a quick answer for the question in this post. In short the problem is like this:

  • A depends on B;
  • A has a transient lifestyle (every time a new instance could be created);
  • A is registered in the parent scope;
  • B is registered in the child scope;
  • how do we resolve A in a child scope?

Of course there could be somewhat straightforward solution like this:

  • Register parent scope as component in every child scope
  • Register A with the lambda expression that will dig get the parent expression and resolve the dependency.

Although this approach is close in spirit to the self-replicating nanorobots, it just does not feel right.

PS: Next post on autofac contains link to .NET 2.0 compatibility .cs file. This file is all you need in order to compile autofac to target .NET 2.0.

Tags: , ,

4 Comments to One more interesting and fresh .NET IoC container: autofac

Nicholas Blumhardt
January 10, 2008

Hi Rinat,

Thanks for your comment over on my blog. I’m glad autofac makes sense to you :)

The scenario you’ve described (at a first glance) looks very straightforward in Autofac to me:

ContainerBuilder cb = new ContainerBuilder();
cb.Register(c => new A(c.Resolve<B>()))
.WithScope(InstanceScope.Factory);

Container parent = cb.Build();

Container child = cb.CreateInnerContainer();
ContainerBuilder childBuilder = new ContainerBuilder();
childBuilder.Register(c => new B());
childBuilder.Build(child);

A a = child.Resolve<A>(); // will now work as you expect.

What you’ve touched on is exactly the reason that the expressions take the container (through IContext) as their first argument, rather than use a closure to resolve dependencies from the container. When the resolve is done in the child scope, the _child_ container will be passed as the argument to the expression creating A.

Happy to go into this further if you’re interested.

Nick

Nicholas Blumhardt
January 10, 2008

Oops, your commenting system accepts HTML… That code should read:

ContainerBuilder cb = new ContainerBuilder();
cb.Register(c => new A(c.Resolve<B>()))
  .WithScope(InstanceScope.Factory);

Container parent = cb.Build();

Container child = cb.CreateInnerContainer();
ContainerBuilder childBuilder = new ContainerBuilder();
childBuilder.Register(c => new B());
childBuilder.Build(child);

A a = child.Resolve<A>();

Rinat Abdullin
January 10, 2008

Nicholas, thank you very much for this description!

I should’ve figured out myself, that the lambda will do the trick by pulling the component out of the current context.

This elegant flexibility is awesome! And that specific implementation is a great solution to the MicroKernel’s problem (their dependency resolution takes place in the context where the component has been registered).

I’ll definitely spend a bit more time with the autofac IoC.

Arturas
May 12, 2008

Just a couple of days ago we released our lightweight .NET inversion of control (IoC, dependency injection) container called Winter4net. It’s fast, compact and scalable. Visit our site for more details - http://www.winter4.net or you can contact us through the feedback form. Oh i forgot to mention that we offer free community efition binary license!

Leave a comment

RSS

Search

Archives