Wednesday, February 4, 2009

Service Locator

IF you just read my page on Unity Containers , you may be wondering....
What is a Service Locator all about?
Well, it’s a container too but it doesn’t instantiate anything or manage any lifetimes for you.
For those of you who work on projects that favor inheritance over composition, It offers you decoupling with concrete types. It doesn’t handle instantiation or manage lifetimes for you but its’ still better than a factory.
Say, for example you have a class that depends on two different services whose type is specified at design time, your dependent class must know how to construct each of those services.
A factory still won’t work because Service A and Service B are two different types of objects.
What a Service Locator does is hold a reference to Service A and Service B for you so your dependent class only needs to know how to call the Service Locator and pass in the Type of Service it needs.
Your dependent class calls the Service Locator, passing in the Type of service it needs and the Service Locator will return an instance of the Service.
You can actually combine Service Locator and Unity Container by putting a Unity Container inside a Service Locator. It’s not the most practical thing I’ve heard of but if you run into a situation where you find yourself with two separate Unity Containers sometime in the future.
Unity Container in a Service Locator?
I actually used this approach for when I was refactoring using Test Last Development. I knew that my classes would be refactored for composition from inheritance and that I would use dependency injection at some point, but I wasn’t quite sure how many things I would inject so I just injected a Service Locator with a Unity Container full of all of my services objects inside, next I made the tests pass, and finally I was able to gradually abstract the data, create the interfaces and then just got rid of the Service Locator alltogether.
Refactoring is an entirely different subject, and you can read my page on Test Last Development if you would like more information on my take.






So what does Service Locator look like?
Well, first the bad news is that if you want to inject a unity container you have to create a custom service locator. Yep, you have to create your own by inheriting from ServiceLocatorImplBase. Here’s an example of a service locator. You’ll need to override methods as need in your implementation.
using Microsoft.Practices.ServiceLocation;
using Microsoft.Practices.Unity;

public class MyServiceLocator : ServiceLocatorImplBase
{
private IUnityContainer container;

public MyServiceLocator(IUnityContainer container)
{
this.container = container;
}
protected override object DoGetInstance(Type serviceType, string key)
{
return this.container.Resolve(serviceType, key);
}

protected override IEnumerable DoGetAllInstances(Type serviceType)
{
return this.container.ResolveAll(serviceType);
}
}

Next, you’ll need a unity container to add to the service locator.
///
/// Handles the initialization of the test cases.
///

[TestInitialize]
public void Init()
{
/// Makes FooModel a singleton
var container = new UnityContainer()
.RegisterType(new ContainerControlledLifetimeManager());

/// Inject a FooDependencyObject.
container.Configure()
.ConfigureInjectionFor(new InjectionConstructor(new FooDependencyObject()));

var myServiceLocator = new MyServiceLocator(container);

}

That’s it, your Service Locator has a Unity Container inside.
If you want an instance of a class in your Unity Container, you just ask your Service Locator for it.
this.myServiceLocator.GetInstance().DoStuff();

Regards -c

No comments:

Post a Comment