What should it be called?

Dependency Injection or Service Locator

They are different. Don’t mix them up.

Elye
Elye
Oct 13 · 6 min read
Picture by Sara Bakhshi on Unsplash

Dependency Injection is now a big word in Software world. However it’s a concept is actually pretty simple. Some one stated Dependency Injection is a 25-dollar term for a 5-cent concept.

It is simply passing one dependency to a target object. Wikipedia defines it as

A technique whereby one object supplies the dependencies of another object.

With that definition, every one just name the way one get dependency as Dependency Injection. This is not right. I was equally confused as well 😓

  1. Dependency Injection
  2. Service Locator
  3. Self access or creation. (i.e. instantiate dependencies oneself. Arguably, some doesn’t consider this as dependencies, but this is not the focus of discussion here)

Even Google did state that for it’s Manage dependencies between components

Service Locator wrongly called as Dependency Injection :(

Dependency Injection name is so big, and any way one getting dependencies is called dependency injection by many. With that, the Service Locator pattern of accessing dependency is also called as Dependency Injection, which is not right 😓

E.g. the below post of proposed a solution of accessing dependency using some Environment container, which is a Service Locator, but was named as Dependency Injection

To clarify this, let’s get Martin Fowler’s quote.

With service locator the application class asks for it explicitly by a message to the locator. With (dependency) injection there is no explicit request, the service appears in the application class

There’s a great distinction between them two, and they don’t overlap, with the exception of Dagger 2 (I’ll explain this point later).

What’s the difference?

The blog below is helpful is explaining what Service Locator is in particular.

To make it simpler, their different is just

The dependencies is given to the target object, without the object doing anything. In another word, the dependency is INJECTED into the target object.

The target object, access its dependencies (services) from a locator (container, register etc), that helps to search for the dependencies requested, and provide it to the target object. It is not INJECTED, but LOCATED instead.

Talk in code please…

Drawing and concept is nice, but not crystal clear. Lets code to clear it up.

There are at least 4 approach (caveat: some are considered bad practice)

  1. Constructor Injection. Send in the dependencies through the constructor parameter of the target object. e.g. TargetObject(dependency)
  2. Setter Injection. Having a API function for one to set the dependency externally. e.g. targetObject.setDependency(dependency)
  3. Public variable Injection. Make the dependency variable public and mutable, so externally one could set it (this is what happen in Dagger 2 behind the scene) e.g. targetObject.dependency = dependency
  4. Reflection Injection. Using reflection to access the internal dependency variable belonging to the target object and set it from externally.

Note: You notice all the dependencies are INJECTED into the TargetObject from externally.

This is done within the class.

To make it looks like dependency injection, sometimes it is assigned to a local variable as shown below.

class TargetObject() {
val dependency = globalServiceLocator.getTargetObjectDependency()
}

But sometimes, some may use it is used directly instead.

class TargetObject() {
init {
globalServiceLocator.getTargetObjectDependency().doWork()
}
}

The later approach is less cleaner, as it is hard to quickly identify what the TargetObject is dependent upon.


From the above, both Dependency Injection and Service Locator are distinctly different way of getting dependencies. One is injected externally by others. The others is the object itself is taking it from the ServiceLocator (container).

The below picture sum it all. The target object depends on the medication. One way is to inject into target object, the other is to self service from the container.

Hopefully with this, it is now clearer the different of Service Locator and Dependency Injection.


Android Framework is special. Its Activity and Fragment can only have a default empty constructor. In another word, no dependency can be injected through the constructor. Check out the below for more understanding.

If you look at a class that need Dagger 2 to inject its dependency it will do something as below.

class TargetClass {
@Inject lateinit var dependency1 : Dependency1
@Inject lateinit var dependency2 : Dependency2
@Inject lateinit var dependency3 : Dependency3
init {
DaggerMyComponent.create().inject(this)
}
}

One just need to declare what dependencies it needs by annotate it with @Inject keyword. Then Dagger 2 should automatically inject them (note: the variable is made public so that it could be set)

However, there’s one more step needed. The TargetObject would also need to access the DaggerMyComponent to perform an injection to the class. Arguably it doesn’t need to wire up each dependencies manually, but the fact that it has to access the DaggerMyComponent from within, makes it not fulfilling the definition of Dependency Injection.

With that, Android Dagger was introduced, to remove the explicit need of

DaggerMyComponent.create().inject(this)

From a user point of view, this is now clear from needing manually access the component to inject its dependencies. However, behind the scene, it’s Activity (or Fragment) need to extend from the Android Dagger provided class e.g. DaggerAppCompatActivity. On it’s onCreate function it is as below

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
}

Hence, behind the scene it is still perform a manual work to get its dependencies.

It’s not the issue with Dagger 2, but more towards the limitation of Android Activity/Fragment framework, that makes this unavoidable.

Nonetheless, it is still closer to Dependency Injection, as one doesn’t need to manually locate and wire up its dependencies. Just put @Inject at the front of the dependencies variable, it should automatically be supplied upon the single inject function call to the Component.

The below picture might reflect what Dagger 2 is doing, a self injecting Dependency Injection 😊.


Hopefully with this, we should know there are different ways of Accessing Dependencies. Let’s give Service Locator it’s due honor of calling it out when it is used, instead just calling it Dependency Injection (or DI).

If we have to give one name to them both, let’s simply call it Dependency Accessing (DA), instead of DI.


You could check out my other topics here.

Follow me on medium, Twitter, Facebook or Reddit for little tips and learning on mobile development etc related topics. ~Elye~

Analytics Vidhya is a community of Analytics and Data Science professionals. We are building the next-gen data science ecosystem https://www.analyticsvidhya.com

Elye

Written by

Learning and Sharing Android and iOS Development

Analytics Vidhya

Analytics Vidhya is a community of Analytics and Data Science professionals. We are building the next-gen data science ecosystem https://www.analyticsvidhya.com

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade