DEV Community

Ivan V.
Ivan V.

Posted on

Dependency injection without the decorators

I'm a big fan of dependency injection since I'm working with the front-end a lot, I needed a dependency injection library that is not based on decorators and has a small file size. I couldn't find anything, so I've created one myself.

It's called Pumpa it's around 2KB and this is how it works.

class A {
  static inject=[B]
  constructor(public b:B){}
}
class B {}

const container = new Pumpa()

container.bindClass(A,A)
container.bindClass(B,B)

const instanceA = container.resolve<A>(A)
Enter fullscreen mode Exit fullscreen mode

You can also register function factories

class B{}

function myFactory(b: B) {
  return function resolvedFunction() {
    // do something with b
  }
}

myFactory.inject = [B]

container.bindFactory(myFactory, myFactory)

const fn = container.resolve(myFactory)
fn === resolvedFunction
Enter fullscreen mode Exit fullscreen mode

There is also another way to register values with the container. It is particularly useful when you don't have access to the values you want to register (third-party libraries).

class A {
  //note: there is no static inject property on the class
  constructor(public b:B){}
}
class B {}

const container = new Pumpa()

//alternative way of registering
container.bindClass(A,{value:A,inject:[B]})
container.bindClass(B,B)

const instanceA = container.resolve<A>(A)
instanceA.b === B
Enter fullscreen mode Exit fullscreen mode

It also supports injecting an array of dependencies.

class A {
  static inject = [getArray([A, B, C])]
  constructor(deps: [A, B, C]) {}
}
Enter fullscreen mode Exit fullscreen mode

And that's the gist of it.

It is written in Typescript, it is modeled similarly to the Microsoft tsyringe (which I was using previously).

I've spent a lot of time on the documentation, so head over to the Github repository to see what else the library can do.

I'm open to new ideas and pull requests.

Top comments (0)