Skip to content

NodeJS Contextual Dependency Injection using native async_hooks - IoC

Notifications You must be signed in to change notification settings

devthefuture-org/nctx

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nctx

IoC (Inversion of Control)

NodeJS Contextual Dependency Injection using native async_hooks

see https://nodejs.org/api/async_hooks.html

installation

yarn add nctx

or

npm i nctx

usage example with express

ctx/app.js

const nctx = require("nctx")
module.exports = nctx.create(Symbol("app"))

ctx/req.js

const nctx = require("nctx")

const reqCtx = nctx.create(Symbol("req"))

reqCtx.createAppMiddleware = () => {
  return (req, res, next) => {
    reqCtx.provide(()=>{
      reqCtx.share(req)
      res.on("finish", () => {
        reqCtx.endShare(req)
      })
      reqCtx.set("req", req)
      next()
    })
  }
}
reqCtx.createRouterMiddleware = () => {
  return function (req, _res, next) {
    reqCtx.share(req)
    if (next) {
      next()
    }
  }
}

module.exports = reqCtx

app.js

const express = require("express")
const reqCtx = require("~/ctx/req")

const app = express()

app.use(reqCtx.createAppMiddleware())

// middlewares context
app.use(async (req, _res, next) => {
  const reqLogger = logger.child({ path: req.path })
  reqCtx.set("logger", reqLogger)
  next()
})

const router = express.Router()
router.use(reqCtx.createRouterMiddleware())

app.use(router)

// now you can get contextual logger from anywhere you call reqCtx under async tree
router.get("/", async ()=>{
  const reqLogger = reqCtx.get("logger")
  // the reqLogger is specific to the query
})

fork context

const nctx = require("nctx")

const funcCtx1 = nctx.create()
const func = async () => {
  const foo = funcCtx1.require("foo")
  return `foo=${foo}`
}

const main = async () => {
  funcCtx1.provide(()=>{

    funcCtx1.set("foo", "bar")
  
    const result = await Promise.all([
      
      nctx.fork([funcCtx1], () => {
        funcCtx1.set("foo", "jo")
        // here func is executed under the forked context 1
        return func()
      }),
  
      nctx.fork([funcCtx1], () => {
        funcCtx1.set("foo", "devthejo")
        // here func is executed under the forked context 2
        return func()
      }),
  
      // here func is executed under original context
      func(),
  
    ])

  })


  console.log(result)
}

main()

related libs

Contributing:

We welcome contributions! If you encounter a bug or have a feature suggestion, please open an issue. To contribute code, simply fork the repository and submit a pull request.

This repository is mirrored on both GitHub and Codeberg. Contributions can be made on either platform, as the repositories are synchronized bidirectionally.

For more information:

About

NodeJS Contextual Dependency Injection using native async_hooks - IoC

Resources

Stars

Watchers

Forks

Packages

No packages published