Before we go any further, it is worth explaining what a Service Locator is. The Service Locator is a pattern that abstracts your retriveal of components or services from the underlying container model that is used to house them.
So no matter what container you use, i.e. Castle Windsor, Spring, StructureMap etc pulling anything from the container in code will always be the same and consistent across layers.
Martin Fowler explains it better than I can here: http://www.martinfowler.com/articles/injection.html
All you have to do is write an implementor for the Service Locator to use. You'll note all the famous ones on the site above have already been implemented. But of course these don't work on the CF, so what do we do?
Firstly, you need to download the source code for the CommonServiceLocator as the project needs to be modified slightly. Simply remove all references to the ActivationException.Desktop class as the constructors in that class are not supported on the CF. That is it! - for the service locator project. Now all that remains is the implementor. This depends on what container you are using. We have been using a container called CompactContainer written by Germán Schuager that works well (uses reflection as it supports true dependency injection).
CompactContainer can be downloaded from here: http://code.google.com/p/compactcontainer/ it is freely available under the Apache Licence.
In order to write an implementor for the CommonServiceLocator, all you need to do is write a class that derives from abstract class ServiceLocatorImplBase, then tell the service locator where the instance of the container is and a reference to itself. This class implements IServiceLocator too, so itself can be injected into classes - for whatever reason.
The class is really simple, it could look something like this, here we have named it CompactServiceLocator:
So essentially the above code is fairly simple in that all it is doing is it allows the service locator to call your specific container method. i.e. the implementation of method DoGetInstance() calls the specific container method to get an instance from the container. In this case it is method Resolve(). It is just implementation specific code which will look different from container to container.
public class CompactServiceLocator : ServiceLocatorImplBase
private readonly IContainer _compactContainer;
private bool _disposed;
public CompactServiceLocator(IContainer compactContainer)
_compactContainer = compactContainer;
protected override object DoGetInstance(Type serviceType, string key)
object resolvedObject = null;
// Resolve using a key if we have a key
resolvedObject = _compactContainer.Resolve(key);
// Resolve using type if the object has not been resolved
if(resolvedObject == null && !serviceType.IsNull())
resolvedObject = _compactContainer.Resolve(serviceType);
protected override IEnumerable<object>
private void Dispose(bool disposing)
_disposed = true;
public override void Dispose()
So now you have written an implementor to go along side the Castle Windsor etc adapters, how do you use it? Well first you have to tell the Service Locator the container instance it should use, then set a reference to the service locator interface that maps to itself, like so:
Container container = new Container();Container in this case is the CompactContainer freely available as mentioned above.
ServiceLocator.SetLocatorProvider(() => new CompactServiceLocator(container));
Asking for services is done as follows:
ServiceLocator.Current.GetInstance<IFooBar>();Where IFooBar is your registered interface on the container.
That is it - as easy as that. If anyone would like me to put together a complete solution demoing this, please let me know. I didn't do it as the code is all available on line apart from the CompactContainer ServiceLocator implementor.