How to Decouple IoC Framework Implementation

A DI Container should only be referenced from the Composition Root. All other modules should have no reference to the container.

-Mark Seemann (author of Dependency Injection in .NET)

In other words, you should only need to change one class if you change DI containers.

Constructor injection is normally the right way to go, as others have mentioned. You can inject factory interfaces or Func<T> delegates if you need to create objects on the fly.

I'd also suggest avoiding XML configuration whenever possible.


You can certainly try making an abstraction from the container by declaring an IContainer with say Resolve and Register. I did that a couple of times. Then you would go ahead and implement a Container : IContainer and encapsulate an actual IoC container with your abstraction. I tried that with Unity and Castle Windsor.

But hey, soon I realised that this was really an over-engineering. I then understood that I tried to abstract from abstraction, yet to build another abstraction. This could be fine to learn the concept, but it was a real pain in the neck in a real project. I would highly recommend against an abstraction from IoC container. If you correctly use DI principle it will be fairly easy to change your container anyways.

The code looks overcomplicated, like

//I did this mess with Service Locator
var t = ContainerService.Instance.Resolve<IMyType>();
//others could go further with same Service Locator
var t = IoCFactory.Instance.CurrentContainer.Resolve<IMyType>();

//better way, use --> IoC and DI <--
//when a program starts, or a new instance of the context created
var t = Container.Resolve<IMyType>() //this lives at the bottom of the stack
//and then you just pass IMyType to the constructor of other types    
//you don't need to call Resolve again in the logical cycle

See this post by Ayende.

Yes, they abstracted the Inversion of Control Container. I think that if you need to do that, it is pretty clear that you don’t really get what IoC is all about.


Use constructor injection to communicate what dependencies a class needs. Every container you listed supports it.

Sometimes a piece of code cannot achieve complete container independence, but these cases should be a very small part of your codebase.