Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ivanprodaiko94/hekdi
Dependency Injection for node.js integrated with KOA.js
https://github.com/ivanprodaiko94/hekdi
dependency dependency-injection di injection injector koa koa-router koa2 koajs
Last synced: 3 months ago
JSON representation
Dependency Injection for node.js integrated with KOA.js
- Host: GitHub
- URL: https://github.com/ivanprodaiko94/hekdi
- Owner: IvanProdaiko94
- License: mit
- Created: 2017-06-05T13:36:47.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2018-08-23T08:25:01.000Z (over 6 years ago)
- Last Synced: 2024-11-07T09:03:11.529Z (3 months ago)
- Topics: dependency, dependency-injection, di, injection, injector, koa, koa-router, koa2, koajs
- Language: JavaScript
- Homepage:
- Size: 350 KB
- Stars: 23
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[![Build Status](https://travis-ci.org/IvanProdaiko94/hekdi.svg?branch=master)](https://travis-ci.org/IvanProdaiko94/hekdi)
[![license](https://img.shields.io/github/license/mashape/apistatus.svg)]()
[![npm](https://img.shields.io/npm/dm/hekdi.svg)](https://www.npmjs.com/package/hekdi)
[![npm](https://img.shields.io/npm/dt/hekdi.svg)](https://www.npmjs.com/package/hekdi)# node.js Dependency Injection
### Scale your node.js app with ease.
```bash
npm i hekdi
```![App Example](assets/draw.png)
## Basic usage:
```javascript
// imported.module.js
const { createModule } = require('hekdi');class Dependency1 {
constructor() {
this.name = 'Dependency1';
}
}class Dependency2 {
static get $inject() {
return ['LocalDependency'];
}constructor(d1) {
this.name = 'Dependency2';
this.d1 = d1;
}
}module.exports = createModule({
name: 'ImportedModule',
declarations: [
{ name: 'LocalDependency', strategy: 'singleton', value: Dependency1 },
{ name: 'PublicDependency', strategy: 'service', value: Dependency2 },
{ name: 'Arr', strategy: 'value', value: [1, 2, 3] }
],
exports: ['PublicDependency', 'Arr']
});
``````javascript
// main.module.js
const { createModule } = require('hekdi');
const importedModule = require('./imported.module');class Ctrl {
static get $inject() {
return ['PublicDependency', 'Arr'];
}constructor(publicDep, arr) {
console.log(publicDep, arr);
}
}module.exports = createModule({
name: 'SharedModule',
declarations: [
{ name: 'Controller', strategy: 'singleton', value: Ctrl },
{ name: 'ControllerAs', strategy: 'alias', value: 'Controller' }
],
imports: [ importedModule ]
})
``````javascript
// app.js
const { DI } = require('hekdi');
const MainModule = require('./main.module');
const di = DI.create();di.bootstrap(MainModule);
const ctrl = di.resolve('ControllerAs');
// Dependency2 { name: 'Dependency2', d1: Dependency1 { name: 'Dependency1' } } [ 1, 2, 3 ]
```## Main concepts:
### Top level API:
Top level api is `DI` class that bootstraps main module and serves dependencies from it then.```javascript
const { DI } = require('hekdi');
const di = DI.create();di.module(moduleConfig) // creates new module from config
di.bootstrap(moduleConfig) // register module as main one and resolve dependencies from it
const dep = di.resolve('dependency') // return dependency that was registered to bootstrapped module according to its strategy
```### Modularity:
DI provides modules as a structural unit of app.
- `declarations` array sets own dependencies of this module.
- `exports` array tells what dependencies are available for other modules
- `imports` array will inject exported members from other module to this one```javascript
const { createModule } = require('hekdi');createModule({
name: 'SomeModule',
declarations: [
{ name: 'LocalDependency', strategy: 'singleton', value: class X {} },
{ name: 'PublicDependency', strategy: 'service', value: class Y {} },
{ name: 'Arr', strategy: 'value', value: [1, 2, 3] }
],
exports: ['PublicDependency', 'Arr'], // if '*' set, module will export all of the dependencies including imported
imports: [ AnotherModuleInstance ]
});
// here 'LocalDependency' will be available for injection only for members of this module.
```### Strategies:
- `service` - each time a new instance will be created with `new` keyword.
- `factory` - return the result of plain function call.
- `singleton` - only one instance will be created.
- `value` - just will be returned.
- `constant` - the same as `value` but can't be reassign.
- `alias` - used to create an alias for some dependency.# Koa.js usage:
`hekdi` can be integrated with [koa.js](https://github.com/koajs/koa).
The main concept of framework integration is monkey patching of functions
that are responsible for requests handling.While using koa hakdi monkey patches `use` method.
#### Basic usage:
```javascript
const Koa = require('koa');
const { koaDI } = require('hekdi');
const app = new Koa();const moduleToBootstrap = {
name: 'MainModule',
declarations: [
{ name: 'ctrl', strategy: 'singleton', value: SomeClass },
{ name: 'echo',
strategy: 'value',
value: async (ctx) => {
ctx.body = ctx.request.body;
}
}
],
exports: '*'
};koaDI(moduleToBootstrap, app);
// now di is already bootstrapped and ready to work.
// In koa app you can reach di as `app.context.di`
// In di you can get koa app as `App` dependency.
app.use({
controller: 'ctrl', // if dependency is object
action: 'middleware', // you tell which of its methods will be called
params: [1, 2, 3] // also you can pass additional params to call if needed
});app.use({ action: 'echo' });
// you can reach some function without class creation by passing only action
// to `use` methodapp.use(async (ctx) => { // you still can pass function to `use` method
ctx.body = ctx.request.body;
});app.listen(3000)
```### Usage with router
While using router the story is almost the same:
```javascript
'use strict';const Koa = require('koa');
const Router = require('koa-router');
const bodyParser = require('koa-body-parser');
const { koaDI } = require('hekdi');const app = new Koa();
const router = new Router();const moduleToBootstrap = {
name: 'MainModule',
declarations: [
{ name: 'ctrl', strategy: 'singleton', value: SomeClass },
{ name: 'echo',
strategy: 'value',
value: async (ctx) => {
ctx.body = ctx.request.body;
}
}
],
exports: '*'
};koaDI(moduleToBootstrap, app, router);
app.use(bodyParser());
router
.post(['/', '/test'], { action: 'echo'})
.get('/', {
controller: 'ctrl',
action: 'getHandler',
params: [1, 2, 3]
}).get('/test', async (ctx) => {
ctx.body = 'handled';
});app
.use(router.routes())
.use(router.allowedMethods());app.listen(3000);
```