Dependency Inversion in large-scale TypeScript applications with InversifyJS

Preview:

Citation preview

Dependency Inversion in large-scale TypeScript applications with InversifyJSBy Remo H. Jansen

Coupling between modules occurs when one module directly references another module. In other words, one module “knows” about another module.

The problem: Coupling

Abstractions

Something considered as a general quality or characteristic, apart from concrete realities, specific objects, or actual instances.

Concretions

A concretion is something that relates to or involves specific people, things, or actions rather than general ideas or qualities.

Dependency Injection

Dependency Inversion

Composition root

“A (preferably) unique location in an application where modules are composed together.”

Inversion of Control (IoC) and IoC containers

● Inversion of control is used to increase modularity of the program and make it extensible and flexible.

● The question is: "what aspect of control are we inverting?" The IoC container takes the control over the object composition.

InversifyJSA powerful lightweight inversion

of control container for JavaScript

apps powered by TypeScript

inversify.config.ts

The modules are unaware of each other but the IoC container is aware of all the modules in the application.

Coupling takes place in one unique place.

Declaring kernel modules

Kernel modules are used when your inversify.config.ts file becomes too large.

Declaring kernel middlewareThe middleware is an extension point for InversifyJS. It allows developers to create plugins for InverifyJS.

The internal InversifyJS process:

1. Annotation phase2. Planning phase3. Middleware (optional)4. Resolution phase5. Activation handlers (optional)

Using concretions: Classes

Using abstractions: String literals

● We use string literals to represent interfaces at runtime● String literals can lead to naming collisions be careful!

Using abstractions: Symbols

● Symbols helps us to avoid naming collisions● Symbols might be generated by the TypeScript compiler in the future.

This would eliminate the need for manual annotations when using interfaces!

Controlling the scope of the dependencies

The IoC container takes the control over the lifecycle of the dependencies.

Let’s take a look to some of the InversifyJS features!

Injecting a value

Injecting a class constructor

Injecting a Factory

Auto-factory

Injecting a Provider (async Factory)

Activation handlers

Objects become unaware of cross-cutting concerns and the IoC container takes the control over them!

Multi-injection

Contextual bindings: Tagged bindings

@named(“name”) is an alias of @tagged(“named”, “name”)

Contextual bindings: Named bindings

Create your own decorators

Useful when you are going to apply a @tagged decorator to many entities.

Contextual bindings: @paramName

Only needed if you are planning to compress your application.

Out of the box contextual constraints

InversifyJS includes out of the box implementations of the most common contextual constraints.

Custom contextual constraints

InversifyJS includes some helpers to help you to declare contextual constraints.

Thanks!

$ npm install inversify@2.0.0-beta.1 --save

Beta available now!

Questions?

Thanks!Want to learn more?● http://inversify.io/● @InversifyJS ● https://github.com/inversify/InversifyJS

Recommended