Dependency Injection ?

Dependency Injection (also known as DI), is one of the best Software Engineering principles we can apply in software projects. According to Wikipedia:

In software engineering, dependency injection is a technique whereby one object (or static method) supplies the dependencies of another object. A dependency is an object that can be used (a service). An injection is the passing of a dependency to a dependent object (a client) that would use it. The service is made part of the client’s state.[1] Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern.

DI in statically typed languages

Java was the programming language I have used for longer period in my young career. In 2009, one of my former university colleagues challenged me to switch from PHP to Java: “the promised land”… and somehow I ended up using Java for the next 6 years intensively in production.

Thanks GOD, the migration to Node.js 🚀came afterwards in 2015… and yet: If something I miss from Java, that is the “Spring IOC module” 😥…

There are certainly DI implementations for every programming language or stacks. For statically typed languages like Java or TypeScript, implementations are really impressive, due to the power of interfaces and modern OOP resources like annotations (see TypeScript example).

Let’s analyse a basic example in TypeScript using the inversifyframework:

The DI Container have instantiated the required objects and resolved their dependencies behind the scene. So instead of managing objects creation and their dependencies in our code, a “magic” container is doing this for us 🙌!

DI in JavaScript?

JavaScript is not a statically typed language, it does not support interfaces, neither variable type declaration. Certainly some of the magic of a DI container is simply not possible here, as the system can’t infer the expected dependency type in a “decent” way. However, DI is still possible using JavaScript!

Let’s analyse a basic example in JavaScript using the dizzy framework:

As types can’t be inferred using Class or Interface names, we can use the function parameters name to refer to the dependencies. Let’s get again into this process:

Resolving dependencies using function parameters name

While registering a service, we indicate the dependencies that are required to be resolved first, so we can instantiate the “app” service. Here we use the callback function parameters name to indicate the DI container what dependencies to inject🏌🙌.

Are we then using DI in JavaScript?

If you are a Frontend Developer this days, you are most probably using DI through TypeScript. Just to mention one example:

While DI is pretty used in one way or another for frontend applications (because here we produce a lot of objects 😉), it is not the same case for the backend. I tried to answer my self this question, and I found what I guess is the root cause:

Major backend web frameworks in JavaScript / Node.js does not use DI on their core, thus not in their documentation or “getting started” guides. It is simply not promoted as a good practice. Ultimately causing developers to think:

“Humm, adding a DI framework to rule my application setup might just not be correct!”

In my honest opinion: The adoption of DI techniques in JavaScript backend applications is low, and that is really sad!

As a positive example of promoting DI on the backend we can mention the Nestjs framework, although it is not so popular and uses TypeScript as a required language. Anyways 👏

Conclusions

“Dependency Injection” is only about benefits. Dozens of libraries are out there, ready to make it possible for the JavaScript language, both in the frontend and the backend.

So I want to finish this article by reminding us some of the benefits we get by embracing DI: