A couple of weeks ago I blogged about the common service locator that had just been announced by the Microsoft Patterns and Practices team. I've just updated our current application to use it. Here is what you need to do:
First, download the the binaries from codeplex. You can also get the code and build it yourself. You then need to add the Microsoft.Practices.ServiceLocation assembly to your project.
If, like me, you're using Castle Windsor you should download the code for the Castle Windsor Adaptor. This includes a file called WindsorServiceLocator.cs that you can add to your project. If you are using another IoC container, check the main page of the common service locator codeplex project for the relevant adaptor.
In your application startup code (Global.asax.cs Application_Start() for examle), register the WindsorServiceLocator with the ServiceLocator:
ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container));
You can now grab components from any place in your application using the ServiceLocator static Current property:
var contextService = ServiceLocator.Current.GetInstance<IContextService>();
And there's no direct dependency on Windsor so you can swap in StructureMap, AutoFac, Unity or whatever when the mood takes you.
Now there's a big big caveat with this. You should really only use the static service locator when dependency injection (DI) is not an option. In an MVC Framework application you will typically provide a ControllerFactory that gets controller instances from the IoC container. Every further dependency in the object graph that handles the request should be provided by DI. Even when you need to defer service location, the abstract factory pattern is a better choice than ServiceLocator.
The next thing that needs to happen is for ServiceLocator to be fully leveraged by the MVC Framework code. At the moment you have to use the MvcContrib WindsorControllerFactory, or write your own controller factory. It would be very nice if simply calling SetLocationProvider did the same thing.