Dependency Injection, what in the world is that?

I know you have heard this term so many times, but for everything that is good in this world, what does it mean? I get it, I’ve been there as well. It’s one of those things, you either love it or hate it. Let’s make you love it, if you will.

The purpose of this article is simple – we need to remove some of the fog that surrounds the technical concept called Dependency Injection (or DI), and after understanding what it is and why there’s a need for such concept, you will start loving it.

This is part 1 out of a 3-series articles on Dependency Injection. In upcoming articles we will also cover why do we actually need to apply this concept in our project and also how can we actually achieve such dependency injection with the use of various frameworks.

Awesome! Before we get our feet wet, let me give some other great news – we will try to understand this DI concept while coding, so this will not be just another average theoretical article, you will see some dependency injection in action! Keep in mind that the examples will feature Android code, but we will try to keep it generic so the idea remains the same for every stack you code in.

Oh and last thing before we jump in – let’s establish a basic requirement, just so you know what to expect:

  • Basic to mid programming experience (If it’s in Android then you’re a match, but no worries if your heart is in another place, the concept is the same!)

What is Dependency Injection?

Dependency Injection is a concept that centralizes the object creation process by giving you full power and control over the way entities are created in different places within your project.

You’re right, let’s try to put that into simple terms. Dependency Injection simply means that the container object will always provide all dependencies required to the contained inner object.

This means that if the container (which for us would be the ViewModel) has a dependency – the Repository – and that dependency needs object A and B, instead of leaving the Repository to create its own objects A and B, we will be by applying Dependency Injection and the ViewModel will be in charge of providing object A and B to his Repository.

So, traditionally we instantiate each dependency inside the corresponding class:

This way, in main we don’t have to care about any object creation. There are several problems here that we will bring up in the next section and actually detail them in the upcoming article.

For now, let’s try to apply what we’ve just learned by doing the dependency injection manually and adding dependencies as parameters in constructors:

Alright so right now we can see that the container is in charge of providing the dependencies A and B for his contained object. That’s good, but it seems that nobody manages the container’s dependencies. Let’s do that in main:

Perfect! Now the dependencies are no longer handled by all our components, instead our function main does that.

It’s important to note that Dependency Injection relies on the concept of externalizing the dependencies which is usually handled by an external component. This component usually centralizes most of our dependency provisioning logic and allows us to have one source of truth and to reuse some instances. Let’s create such component so that its only purpose is to handle dependencies!

As you can see, neither our ViewModel nor our Repository are in charge of providing dependencies as this process is externalized in DependencyInjector which takes care of everything.

We’ve wrote enough code for now and we achieved a manual injection. For minor projects, manual injection is just fine, but for more complex projects we will end up using DI frameworks.

Before going into that, we should tackle the big question, why do we need to do this? Couldn’t it work the way it used to?


Why do we need Dependency Injection in our lives?

Obviously it could work the way it used to, but how about scalibility, reusability or testing? I might have pinched a nerve there!

By applying DI, there are several improvements that we can achieve instead of going with the traditional approach of hardcoding the dependencies inside each class:

  • There is less boilerplate code
  • Components are loosely coupled
  • The code is highly testable

We will treat this subject extensively in the upcoming article, subscribe to stay tuned!

I want you focused so take a break, and see ya in the next article! And remember, if you enjoyed this article, you can buy me a coffee using the coffee bottom widget!

7+

1 thought on “Dependency Injection, what in the world is that?

Comments are closed.

%d bloggers like this: