Last active
December 5, 2019 15:02
-
-
Save leobrines/b37fee9865e6fd082a83b7efce8a82c1 to your computer and use it in GitHub Desktop.
Dependency Injection example for NodeJS - Source: https://auth0.com/blog/developing-well-organized-apis-with-nodejs-joi-and-mongo/
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
// This file is to register independent modules and dependencies of each entities, usecase, etc. | |
// | |
// All this is fiction: | |
// infrastructure -> External frameworks | |
// interfaces -> Layer of abstraction of frameworks | |
// | |
import serviceLocator from './config/serviceLocator' | |
serviceLocator.register('webserver', () => { // Generic name | |
return require('./configs/express.js'); // This is independent | |
}) | |
serviceLocator.register('database', () => { | |
return require('./configs/mongoose.js'); // Other independent | |
}) | |
serviceLocator.register('userService', (serviceLocator) => { | |
const userService = require('./UserService')({ // This create a object. The class need database connections | |
database: serviceLocator.get('database') | |
}) | |
return userService; | |
}) | |
module.exports = serviceLocator |
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
import serviceLocator from './container' | |
const database = serviceLocator.get('database') | |
const webserver = serviceLocator.get('webserver') | |
function main () { | |
database.connect(); | |
webserver.start(); | |
} | |
main(); |
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
class ServiceLocator { | |
constructor () { | |
this.dependencyMap = {}; | |
this.dependencyCache = {}; | |
} | |
register (name, constructor) { | |
validate(name, constructor) | |
this.dependencyMap[name] = constructor; | |
} | |
get (name) { | |
const constructor = this.dependencyMap[name]; | |
validate(name, constructor); | |
if (this.dependencyCache[name] === undefined) { | |
const dependency = constructor(this); | |
if (dependency) | |
this.dependencyCache[name] = dependency; | |
} | |
return this.dependencyCache[name]; | |
} | |
clear () { | |
this.dependencyCache = {}; | |
this.dependencyMap = {}; | |
} | |
} | |
function validate (name, constructor) { | |
validateName(name); | |
validateConstructor(name, constructor); | |
} | |
function validateName (name) { | |
if (typeof name !== 'string' && !name) | |
throw new Error('Invalid dependency name provided'); | |
} | |
function validateConstructor (name, constructor) { | |
const isNotFunctionError = ': Dependency constructor is not a function'; | |
if (typeof constructor === 'function') | |
throw new Error(name + isNotFunctionError); | |
} | |
module.exports = new ServiceLocator(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment