Back in August, Jeremy Miller posted It's time for IoC Container Detente. In this post, he argued that the embarrassment of riches we currently have around .NET IoC/DI containers are actually hindering the adoption of the Inversion of Control. Anyone who wants to write a library that uses a DI container has to choose one and force that decision on the library's users. Either that or hide the container under the hood and suddenly one application can end up with two or three different, incompatible, containers, each of which needs to be configured. What was really needed was a simple, small, standard adapter interface that library authors could build against.
Oren Eini sent out an email to a bunch of DI container authors (yours truly included) suggesting that we just build it. After batting ideas around for a while we ended up with this:
public interface IServiceLocator : IServiceProvider
object GetInstance(Type serviceType);
object GetInstance(Type serviceType, string key);
IEnumerable<object> GetAllInstances(Type serviceType);
TService GetInstance<TService>(string key);
This interface includes sufficient overloads to be convenient for users while mapping well to most DI containers currently out there.
We specifically chose not to include container configuration or type registration in the interface. The general conclusion is that this is the area where containers differ the most, and offer the most unique values. Forcing a common registration semantic would just emasculate them. And, looking at how containers are best used, in most cases the containers are set up in a bootstrap phase at the start of the application and then you just resolve stuff, so it seems to work out pretty well.
I just pushed the button to publish our binaries containing this interface (and a few other useful bits) on Codeplex. We're starting out with Castle Windsor, Spring.NET, and Unity adapters, with more to come soon.
If you're writing a library or framework and want to use a DI container, but don't have a need for specific features of one container or the other, please consider using this small isolation layer. This way your users get to pick the container they want. For example, right now Enterprise Library is pretty well wedded to Unity and ObjectBuilder2. For the next version, I'm planning to use this interface instead and break that tight coupling, so Entlib can play nicer with other frameworks and libraries.
I'm pretty happy with the way this came out, particularly with the way the project ran. Lots of great collaboration both inside and outside of Microsoft. Hopefully a sign of things to come.