Skip to content

Instantly share code, notes, and snippets.

@MartinMuzatko
Last active October 8, 2020 12:31
Show Gist options
  • Save MartinMuzatko/66327dded2f90cca64960569dae2ff8c to your computer and use it in GitHub Desktop.
Save MartinMuzatko/66327dded2f90cca64960569dae2ff8c to your computer and use it in GitHub Desktop.
Different types of Dependency Injection in JavaScript
// Dependency Injection
// single dep
const random = Math => Math.random()
random({ random: () => 4 }) // 4
random(Math) // anything between 0 - 1
// multiple deps - as parameters
const report = async (log, saveToDb, Date, message) => {
log(`{new Date()}: ${message}`)
await saveToDb(new Date(), message)
}
// cumbersome...
// multiple deps - destructured
/**
* @param {object} context
* @param {object} context.db
* @param {function} context.log
*/
const readUserFromDbById = async ({ db, log }, id) => {
const user = await db.where({ id }).fetch()
log(`user fetched: ${user.name}`)
return user
}
// multiple deps - object
/**
* @param {object} context
* @param {object} context.db
* @param {function} context.log
*/
const readUserFromDbById = async (context, id) => {
const user = await context.db.where({ id }).fetch()
context.log(`user fetched: ${user.name}`)
return user
}
// other words: ctx (koa style), deps, dependencies, options, settings, opts
const bookshelf = require('bookshelf')
readUserFromDbById({ db: { where: () => ({ fetch: () => ({ name: 'joe' }) }) }, log: () => {} }, 1) // { name: 'joe' }
readUserFromDbById({ db: bookshelf, log: console.log }, 1)
// user fetched: joe
// { name: 'joe' } or Error or null or { name: null } or ...
// delayed execution
const readUserFromDbById = context => async id => {} // readUserFromDbById(ctx)(3)
const readUserFromDbById = R.curry((context, id) => {}) // readUserFromDbById(ctx)(3) or readUserFromDbById(ctx, 3)
// Alternatively: partial application
const readUserFromDbById = async (context, id) => {} // readUserFromDbById(ctx, 3)
readUserFromDbByIdWithContext = R.partial(readUserFromDbById, context)
readUserFromDbByIdWithContext(3)
// module dependencies: function level
const list = ctx => async () => ctx.fs.readJSON('apps.json') // [1,2,3]
const get = ctx => async id => (await list(ctx))[id] // 1
get({ fs })(1) // 1
get({ fs: { readJSON: () => [2,3,4] } })(1) // 2
// module dependencies: dependency level
const list = ctx => async () => ctx.fs.readJSON('apps.json') // [1,2,3]
const get = ctx => async id => (await ctx.list(ctx))[id] // 1
get({ list, fs })() // 1
get({ list: () => [2] })(1) // 2
// closure dependency injection
const appsFactory = ctx => {
const list = () => ctx.fs.readJSON('apps.json')
const get = async () => (await list())[0]
return {
list,
get,
}
}
const apps = appsFactory(ctx)
apps.list() // [1,2,3]
// but calling list() directly is not possible anymore
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment