Should You Use An IOC Container In Your JavaScript UI App?

Introduction

In a UI app we need to separate code structures to abide by the single responsibility and reduce coupling between interdependent files that our components will rely upon.

Normally, we use a module loader to import dependencies which works to a standard such as commonJS and we use tools like Babel or Webpack to ensure these dependencies can be accessed when our app is loaded and run in a browser.

Whilst modules are powerful they don’t give us enough control over our dependencies, so we should use an IOC container

Dependency Types

In a UI app there are two types of dependency.

The first is a runtime dependency where we dynamically call other parts of our app as our code is executing.

The other is a source code dependency which statically links some place in our app to another place. Source code dependencies eventually become runtime dependencies, but the dependency physically exists in the files beforehand.

When we talk about dependency management, we often talk about reducing coupling using a technique called Dependency Inversion, in short this means removing source code dependencies and replacing them with runtime dependencies to make our code more flexible.

Whilst we could use things like inline switches to give us dynamic dependencies and help us implement Dependency Inversion, we don’t want to bloat our code with this approach. So instead we use something called a container that does it for us. The container is a proxy object which will resolve our dependencies for us.

At the most basic level a container lets us replace this sort of code….

// nothing
class MyClass {
    constructor() {
        console.log('do stuff') // prints do stuff
    }
}

With something that looks like this…

// inversion of control
class MyClass {
    constructor() {
        Container.get('Dependency').doStuff() // prints do stuff
    }
}

In the second example we are asking the container to get our dependency module loaded. We get the right dependency by passing a token called ‘Dependency’ into the container.

By accessing our dependency via this token (or identifier) we can bury the source code dependency behind our Container. But why would we want to do that?

Lifecycle

In our UI Architecture Academy we teach students how to categorise all of their dependencies into two types, Transients and Singletons.

Transients mean that when you access them you get a completely new instantiation every time you ask for them.

With Singletons you do not (you get the same one). And the importance is significant because being able to centrally control what is a Singleton and what is a Transient in your app enables you to centralise how long these dependencies exist.

This opens up many opportunities for enhanced design of a Single Page Application. For example in our training we teach students how to leverage Singletons to build a more simple and flexible state system which has the power to be reset when the time is right.

We can get pure control over state in our app without using excessive tools like React-Redux, meaning state becomes more fluid and deeply connected to our UI architecture.

Conclusion

Dependencies in a JavaScript UI app are normally managed through the module pattern with something like Webpack.

But this pattern has limitations because its ability to control the lifecycle of dependencies is limited and it does not easily allow the dynamic changing of dependencies at runtime.

An IOC container allows the declaration of dependencies behind a proxy object. When this happens, we can more easily control whether those dependencies are Transient or Singleton.

Having this sort of control lets us open up design opportunities and better UI architecture in our app.

Some common JavaScript IOC containers are, Inversify, Simple DI and the Angular Injector module.

Happy architecting ;-)


Author: Pete Heard

Pete is the founder of Logic Room. He designs the companies core material for JavaScript architecture, test automation and software team leadership.

LinkedIn

Want to learn 5 critical lessons for framework-agnostic JavaScript UI app design and structure?

Download our 28-page book exploring big picture ideas to help you create better architecture with any UI framework (inc. React, Angular or Vue).

Download
Close

50% Complete

Book Trial

Please fill out your details if you would like to trial our system.