Last active
October 8, 2020 12:31
-
-
Save MartinMuzatko/66327dded2f90cca64960569dae2ff8c to your computer and use it in GitHub Desktop.
Different types of Dependency Injection in JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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