@graphity/container

Super slim depdency injection container with Async/Promise for Javascript(& Typescript).

Usage no npm install needed!

<script type="module">
  import graphityContainer from 'https://cdn.skypack.dev/@graphity/container';
</script>

README

Graphity - Container

Downloads Version License Typescript
dependencies Status

Super slim DI(Depdency Injection) container with Async/Promise for Javascript(& Typescript).

Installation

npm install @graphity/container --save

Usage

import { Container } from '@graphity/container'

const container = new Container()

Bind simple value

container.instance('obj1', {message: 'this is obj1'})
container.instance('obj2', {message: 'this is obj2'})

await container.boot() // boot!

console.log(container.get('obj1')) // {message: 'this is obj1'}
console.log(container.get('obj2')) // {message: 'this is obj2'}

console.log(container.get('obj1') === container.get('obj1')) // true
console.log(container.get('obj2') === container.get('obj2')) // true

Bind promise value

function promise1() {
  return new Promise(resolve => resolve({message: 'this is promise1'}))
}
async function promise2() {
  sleep(500)
  return {message: 'this is promise2'}
}
container.instance('promise1', promise1())
container.instance('promise2', promise2())

await container.boot() // boot!

console.log(container.get('promise1')) // {message: 'this is promise1'}
console.log(container.get('promise2')) // {message: 'this is promise2'}

console.log(container.get('promise1') === container.get('promise1')) // true
console.log(container.get('promise2') === container.get('promise2')) // true

Bind resolver

container.resolver('resolver1', () => ({message: 'this is resolver'}))
container.resolver('resolver2', () => {
  return new Promise(resolve => {
    resolve({message: 'this is promise resolver'})
  })
})
container.resolver('resolver3', async () => {
  sleep(500)
  return {message: 'this is async resolver'}
})

await container.boot() // boot!

console.log(container.get('resolver1')) // {message: 'this is resolver'}
console.log(container.get('resolver2')) // {message: 'this is promise resolver'}
console.log(container.get('resolver3')) // {message: 'this is async resolver'}

Bind class

import { Inject } from '@graphity/container'

class Driver {
}

class Connection {
  public constructor(@Inject('driver') public driver: Driver) {
  }
}
container.bind('driver', Driver)
container.bind('connection', Connection)

await container.boot() // boot!

const connection = container.get<Connection>('connection')

console.log(connection) // Connection { driver: Driver {} }
console.log(connection.driver) // Driver {}

create

import { Inject } from '@graphity/container'

class Connection {
}

class Controller {
  public constructor(@Inject('connection') public connection: Connection) {
  }
}

container.bind('connection', Connection)

await container.boot()

const controller = await container.create(Controller)

console.log(controller) // Controller { connection: Connection {} }

invoke

import { Inject } from '@graphity/container'

class Connection {
}

class Controller {
  public retrieve(@Inject('connection') connection: Connection) {
    return connection
  }
}

container.bind('connection', Connection)

const controller = new Controller()

await container.boot()

console.log(await container.invoke(controller, 'retrieve')) // Connection { }

Service Provider

providers/typeorm.ts

import { Provider } from '@graphity/container'
import { Connection, createConnection } from 'typeorm'

export const typeorm: Provider = {
  register(app) {
    const DB_HOST = process.env.DB_HOST || 'localhost'
    const DB_DATABASE = process.env.DB_DATABASE || 'test'
    const DB_USERNAME = process.env.DB_USERNAME || 'root'
    const DB_PASSWORD = process.env.DB_PASSWORD || 'root'
    app.resolver(Connection, () => {
      return createConnection({
        type: 'mysql',
        host: DB_HOST,
        database: DB_DATABASE,
        username: DB_USERNAME,
        password: DB_PASSWORD,
        /* ... */
      })
    })
  },
  async close(app) {
    const connection = await app.get(Connection)
    await connection.close()
  },
}

controllers/user-controller.ts

import { Inject } from '@graphity/container'
import { Connection, Repository } from 'typeorm'
import { User } from '../entities/user.ts'

export class UserController {
  public constructor(
    @Inject(Connection) public connection: Connection,
    @Inject(Connection, conn => conn.getRepository(User)) public repoUsers: Repository<User>,
  ) {
  }

  public users() {
    return this.repoUsers.find()
  }

  /* ... */
}

entry.ts

import { Container } from '@graphity/container'
import { typeorm } from './providers/typeorm'
import { UserController } from './controllers/user-controller'

const app = new Container()
app.register(typeorm)

await app.boot()

const userController = await app.create(UserController)
await userController.users() // call controller!