Previously, we saw how we can use a Service Locator in order to prevent ‘newing‘ of objects in our code. However, everything comes with a price. Though we will talk about this in detail, but just to give you a gist of it, a service locator is an anti-pattern as it hides the class dependencies.

 

Commerce Application Example

The example we are following is from our last post, however, there are some modifications. For instance, we are not using any DI container to resolve the dependencies, rather, we are using a static Service Locator to do so.

The Service Locator is used as a replacement for the new operator. Given that, I have to admit this is no fancy locator, yet serves the purpose and looks like this:

 

While everything looks fine at first sight, there are some issues with our code. Let’s explore them one after another.

 

Using Commerce API

Assume that the Commerce class has been provided to us as an API from some third party, and we are just consuming it.

The Visual Studio IntelliSense does not indicate if Commerce itself has any dependencies. Rather, the developer gets an impression that he/she can create a Commerce object using its default constructor. Build the application and it will surely be successful. But, what happens at the run time is quite interesting.

When the application is run, we get a KeyNotFoundException. Reason being that the developer is not aware of the fact that he/she needs to register the dependencies of Commerce class with some locator. In fact, the developer does not even know if a service locator exists.

As a result, it turns out to be a real bad developer experience with the API. And, not to mention, if I were the developer, it will surely be annoying for me. Being an anti-pattern, the service locator hides details about a class’s dependencies from a developer.

 

Using an Abstract Service Locator

Finally, let’s try to change our service locator a bit, and abstract it to an Interface. Owing to that, we have ILocator, and its concrete implementation as Locator. Given that, now it becomes necessary for the Commerce class to explicitly declare its dependency on ILocator.

If you try this out, Visual Studio IntelliSense can now inform the user that the class is expecting an implementation of ILocator. However, this much piece of information is not enough. We are still not aware of the services used by the Commerce class.

Above all, the code in above image compiles and we can successfully call the ProcessOrder method on the object. However, at run time we will still get a KeyNotFoundException as before. This is because we are not aware of the services being used by the Commerce class.

 

Summary

In reality, the problem with service pattern is that it hides a class’s dependencies and is a bona-fide anti-pattern. In fact, it takes away a developer’s clarity about the class he/she is using. While we have so many issues with the service locator, using constructor injection can save our life.

Not to mention, there can be a scenario where a service locator serves its purpose at it’s best. However, through this post I just shared my opinion about a service locator being an anti-pattern. It would be great to receive any feedback on this topic. Please do share your opinion through comments.


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.