From da706a9c5a335093ee36a1ef46ad1a81a57a6757 Mon Sep 17 00:00:00 2001 From: garrettmills Date: Fri, 15 Nov 2019 21:30:27 -0600 Subject: [PATCH] Big Bang --- App.js | 12 ++++++++++++ DependencyInjector.js | 14 ++++++++++++++ Injectable.js | 11 +++++++++++ README.md | 6 ++++++ Service.js | 5 +++++ ServiceContainer.js | 28 ++++++++++++++++++++++++++++ index.js | 9 +++++++++ 7 files changed, 85 insertions(+) create mode 100644 App.js create mode 100644 DependencyInjector.js create mode 100644 Injectable.js create mode 100644 README.md create mode 100644 Service.js create mode 100644 ServiceContainer.js create mode 100644 index.js diff --git a/App.js b/App.js new file mode 100644 index 0000000..fa4a87c --- /dev/null +++ b/App.js @@ -0,0 +1,12 @@ +const Injectable = require('./Injectable') + +class App extends Injectable { + static services = ['emailLogging'] + run() { + setInterval(() => { + this.emailLogging.error('Haha made ya\' look!') + }, 5000) + } +} + +module.exports = exports = App diff --git a/DependencyInjector.js b/DependencyInjector.js new file mode 100644 index 0000000..274f51a --- /dev/null +++ b/DependencyInjector.js @@ -0,0 +1,14 @@ +const ServiceContainer = require('./ServiceContainer.js') + +class DependencyInjector { + constructor() { + this.container = new ServiceContainer() + } + + // Injects the dependencies into an uninstantiated class + make(Class) { + return Class.__inject(this.container) + } +} + +module.exports = exports = DependencyInjector diff --git a/Injectable.js b/Injectable.js new file mode 100644 index 0000000..222595b --- /dev/null +++ b/Injectable.js @@ -0,0 +1,11 @@ +class Injectable { + static services = [] + + static __inject(container) { + this.services.forEach(serviceName => { + this.prototype[serviceName] = container.getService(serviceName) + } + } +} + +module.exports = exports = Injectable diff --git a/README.md b/README.md new file mode 100644 index 0000000..afb7f74 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# Basic Dependency Injection +## In less than 100 lines of pure, ES6 JavaScript + +This is a very bare-bones dependency injector implementation based on the ES6 classes. It's meant to illustrate the feasibility and benefits of using a service-based dependency injector for Node.js/JavaScript applications. + +I discuss this project in greater depth in my blog post [here](https://garrettmills.dev/blog). \ No newline at end of file diff --git a/Service.js b/Service.js new file mode 100644 index 0000000..4c1b62d --- /dev/null +++ b/Service.js @@ -0,0 +1,5 @@ +class Service { + +} + +module.exports = exports = Service diff --git a/ServiceContainer.js b/ServiceContainer.js new file mode 100644 index 0000000..b3df940 --- /dev/null +++ b/ServiceContainer.js @@ -0,0 +1,28 @@ +const LogHelper = require('./LogHelper') +const EmailLogHelper = require('./EmailLogHelper') + +class ServiceContainer { + constructor() { + // We define the service classes here, but we won't + // instantiate them until they're needed. + this.definitions = { + logging: LogHelper, + emailLogging: EmailLogHelper, + } + + // This is where the container will store service instances + // so they can be reused when requested. + this.instances = {} + } + + getService(serviceName) { + // Create a service instance if one doesn't already exist. + if ( !this.instances[serviceName] ) { + const ServiceClass = this.definitions[serviceName] + this.instances[serviceName] = new ServiceClass() + } + return this.instances[serviceName] + } +} + +module.exports = exports = ServiceContainer diff --git a/index.js b/index.js new file mode 100644 index 0000000..b8d746e --- /dev/null +++ b/index.js @@ -0,0 +1,9 @@ +// Create the dependency injector instance for the application +const DI = require('./DependencyInjector') +const di = new DI() + +// Now, create the instance of our application using the DI to inject services +const App = di.make(require('./App')) +const app = new App() // Has access to the emailLogging service + +app.run();