IoC Container Vs. Service Locator

I had a conversation over the weekend with one of my colleagues because I didn't understand the difference between an Inversion of Control (IoC) container and a Service Locator. After our twitter conversation, I had to go back and read the article by Martin Fowler on the topic. Although the article is dated, it provides some valuable information. That information along with my colleague's information clarified the difference.

The confusion was mostly because both tools provide similar services, both provide run time resolution of dependencies. Also when improperly used, an IoC container can be used in the same fashion as a Service Locator can- as was the case in one of my former projects.

Before I get going too far, let me explain what I mean when I say "run time resolution of dependencies". In order to write testable code in OO we have to write classes that are loosely coupled. No coupling at all would be optimal (for testability), but as any programmer knows, that is just not possible At some point a class is going to depend on another class. This other class may have dependencies on resources that are not available during test execution. So how do we get around this? The answer is by coding against abstractions. In C# we use interfaces, in other languages that may be abstract classes. In other words, we code against a contract. The dependent class does not need to know about the implementation details, only the contract. That is to say, if we provide the class this set of parameters it will provide us the agreed result. As my former project lead liked to say "It's a black box, you put in corn and out comes cornflakes. How the cornflakes are made is irrelevant".

Ok, so now our dependent class has an abstraction, big deal, at some point the real object will have to be created and you simply can't new an interface or an abstract class. Therefore, at some point we will have to call new on the concrete class that implements the abstraction. That's where either the Service Locator or IoC tool come in. The Service Locator can be thought of as a container itself, after all it does contain the information (or possibly the instance) to create the concrete class. The IoC container can also be used the same way as a Service Locator, when improperly used.

The Service Locator would be called something like the following:

IMyType myObject = (IMyType)myServiceLocator.GetService(typeof(IMyType));

Where we would pass in the type of the interface and it would return the concrete class. (Ignore the fact that I am not using generics, I didn't want to get to wrapped in the semantics. If you have the capability to use generics please do so.) This type of code would be sprinkled through out our code. We need a service here or there? We just call the Service Locator and request it. Keep in mind that we could use the IoC tool of our choice the same way, but if that is all we are using an IoC tool for, we are seriously under-utilizing it.

The IoC tool on the other hand may be called in the following manner:

IMyType myObject = (IMyTYpe)SomeIoCTool.Resolve(typeof(IMyTYpe));

Wait a minute! what's the difference?! Well from those two lines nothing, except for the variable and method names, which are fictional to begin with (Please refer to your tool of choice for the semantics of the tool). The real difference is that with an IoC tool you have dependency injection capabilities. This means that, for example, if your concrete object has a parameterized constructor, the dependencies will be injected by the IoC tool. The IoC tool may also have the capability to inject dependencies on properties and methods. The Service Locator will only work with the default parameterless constructor and does not have the capability to perform dependency injections. This also means that if you have a hierarchical object where the object has children and they have grand-children and they have little great-grand children... well you get the picture. And those descendants have dependencies as well, they will also be injected with the appropriate dependencies. The IoC tool has the capability to build the entire object graph from the abstractions.

There are many more features that IoC tools possess, but for the purpose of this article the features mentioned are sufficient.

In case you are wondering how the internal workings of either tool allow them to resolve dependencies, the answer to that question can be summed up in two words: registration and reflection. Somewhere in the entry point to our process we told the Service Locator or IoC container to provide us with a particular concrete class whenever we asked for a particular interface. It would look something like the following:

MyTool.WhenAskedFor(typeof(IMyType)).Provide(typeof(MyService));

There is of course more to the Service Locator and the IoC container, but for the most part this is the basic concept.

In summary of this long winded article, the main difference between a Service Locator is that the Service Locator will be sprinkled throughout the code where needed, the sprinkling is mostly because it cannot perform dependency injection. The IoC tool will usually not be sprinkled through out the code. Since it has the capability to perform dependency injections, it can build the entire object graph from scratch. Also, for this reason it can resolve dependencies earlier in the process that the Service Locator can.

The Service Locator can be something as simple as a class with a hashtable that maps the interface type and the concrete type. Using reflection, it can construct the appropriate type at run time. Why is important to create the type at run time. Well because we need the capability to swap it out during our tests so that our test can concetrate on the logic. The IoC tool is way more feature rich and is usually a third party tool that can; construct and object with all dependencies, build up an object's dependencies after construction, perform Aspect Oriented Programming (AOP) capabilities and so on and so forth.

If you are interested in learning more about IoC tools please visit the following links.

IoC Tools
Structure Map
Unity
Windsor

Service Locator in Java

Comments

Derick Bailey said…
great post, Fernando! I had IoC vs ServiceLocator confused for the last 3 years, honestly. I had to go back and re-read that Fowler article a few times in the last week before it really sunk in.

Be careful about saying "coding against abstractions. In C# we use interfaces" - abstraction does not imply interface, even in C#.

http://www.lostechies.com/blogs/derickbailey/archive/2008/10/20/dependency-inversion-abstraction-does-not-mean-interface.aspx
Fernando Zamora said…
Derick, you are absolutely right. I didn't give it think it trough when I wrote that line. Abstractions appear in every language in many different forms. Anything that hides the implementation details for that matter is a form of abstraction. Abstraction is the "what" hiding the "how".
A service locator may as well inject dependencies (using itself to construct them). There is no difference between Service Locator and IoC container if you take them in isolation.

The only difference is how you use them in your application.

Popular posts from this blog

Simple Example of Using Pipes with C#

Difference Between Adapter and Bridge Design Patterns

Remote Access to Your Home Desktop Using No-IP