{"id":26621358,"url":"https://github.com/IvanProdaiko94/hekdi","last_synced_at":"2025-03-24T09:15:03.466Z","repository":{"id":57131569,"uuid":"93407486","full_name":"IvanProdaiko94/hekdi","owner":"IvanProdaiko94","description":"Dependency Injection for node.js integrated with KOA.js","archived":false,"fork":false,"pushed_at":"2018-08-23T08:25:01.000Z","size":358,"stargazers_count":23,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-17T22:06:42.769Z","etag":null,"topics":["dependency","dependency-injection","di","injection","injector","koa","koa-router","koa2","koajs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/IvanProdaiko94.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-05T13:36:47.000Z","updated_at":"2024-11-04T09:46:41.000Z","dependencies_parsed_at":"2022-08-31T20:00:56.123Z","dependency_job_id":null,"html_url":"https://github.com/IvanProdaiko94/hekdi","commit_stats":null,"previous_names":["ivanprodaiko94/injector"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IvanProdaiko94%2Fhekdi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IvanProdaiko94%2Fhekdi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IvanProdaiko94%2Fhekdi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IvanProdaiko94%2Fhekdi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/IvanProdaiko94","download_url":"https://codeload.github.com/IvanProdaiko94/hekdi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244925201,"owners_count":20532873,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dependency","dependency-injection","di","injection","injector","koa","koa-router","koa2","koajs"],"created_at":"2025-03-24T09:15:02.145Z","updated_at":"2025-03-24T09:15:03.455Z","avatar_url":"https://github.com/IvanProdaiko94.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/IvanProdaiko94/hekdi.svg?branch=master)](https://travis-ci.org/IvanProdaiko94/hekdi)\n[![license](https://img.shields.io/github/license/mashape/apistatus.svg)]()\n[![npm](https://img.shields.io/npm/dm/hekdi.svg)](https://www.npmjs.com/package/hekdi)\n[![npm](https://img.shields.io/npm/dt/hekdi.svg)](https://www.npmjs.com/package/hekdi)\n\n\n# node.js Dependency Injection\n\n### Scale your node.js app with ease.\n\n```bash\nnpm i hekdi\n```\n\n![App Example](assets/draw.png)\n\n## Basic usage:\n\n```javascript\n// imported.module.js\nconst { createModule } = require('hekdi');\n\nclass Dependency1 {\n  constructor() {\n    this.name = 'Dependency1';\n  }\n}\n\nclass Dependency2 {\n  static get $inject() {\n    return ['LocalDependency'];\n  }\n\n  constructor(d1) {\n    this.name = 'Dependency2';\n    this.d1 = d1;\n  }\n}\n\nmodule.exports = createModule({\n  name: 'ImportedModule',\n  declarations: [\n    { name: 'LocalDependency', strategy: 'singleton', value: Dependency1 },\n    { name: 'PublicDependency', strategy: 'service', value: Dependency2 },\n    { name: 'Arr', strategy: 'value', value: [1, 2, 3] }\n  ],\n  exports: ['PublicDependency', 'Arr']\n});\n```\n\n```javascript\n// main.module.js\nconst { createModule } = require('hekdi');\nconst importedModule = require('./imported.module');\n\nclass Ctrl {\n  static get $inject() {\n    return ['PublicDependency', 'Arr'];\n  }\n\n  constructor(publicDep, arr) {\n    console.log(publicDep, arr);\n  }\n}\n\nmodule.exports = createModule({\n  name: 'SharedModule',\n  declarations: [\n    { name: 'Controller', strategy: 'singleton', value: Ctrl },\n    { name: 'ControllerAs', strategy: 'alias', value: 'Controller' }\n  ],\n  imports: [ importedModule ]\n})\n```\n\n```javascript\n// app.js\nconst { DI } = require('hekdi');\nconst MainModule = require('./main.module');\nconst di = DI.create();\n\ndi.bootstrap(MainModule);\n\nconst ctrl = di.resolve('ControllerAs');\n// Dependency2 { name: 'Dependency2', d1: Dependency1 { name: 'Dependency1' } } [ 1, 2, 3 ]\n```\n\n## Main concepts:\n\n### Top level API:\nTop level api is `DI` class that bootstraps main module and serves dependencies from it then.\n\n```javascript\nconst { DI } = require('hekdi');\nconst di = DI.create();\n\ndi.module(moduleConfig) // creates new module from config\n\ndi.bootstrap(moduleConfig) // register module as main one and resolve dependencies from it\n\nconst dep = di.resolve('dependency') // return dependency that was registered to bootstrapped module according to its strategy\n```\n\n### Modularity:\n\nDI provides modules as a structural unit of app.\n- `declarations` array sets own dependencies of this module.\n- `exports` array tells what dependencies are available for other modules\n- `imports` array will inject exported members from other module to this one\n\n```javascript\nconst { createModule } = require('hekdi');\n\ncreateModule({\n  name: 'SomeModule',\n  declarations: [\n    { name: 'LocalDependency', strategy: 'singleton', value: class X {} },\n    { name: 'PublicDependency', strategy: 'service', value: class Y {} },\n    { name: 'Arr', strategy: 'value', value: [1, 2, 3] }\n  ],\n  exports: ['PublicDependency', 'Arr'], // if '*' set, module will export all of the dependencies including imported \n  imports: [ AnotherModuleInstance ]\n});\n// here 'LocalDependency' will be available for injection only for members of this module. \n```\n\n### Strategies:\n- `service` - each time a new instance will be created with `new` keyword.\n- `factory` - return the result of plain function call.\n- `singleton` - only one instance will be created.\n- `value` - just will be returned.\n- `constant` - the same as `value` but can't be reassign.\n- `alias` - used to create an alias for some dependency.\n\n# Koa.js usage:\n\n`hekdi` can be integrated with [koa.js](https://github.com/koajs/koa).\n\nThe main concept of framework integration is monkey patching of functions\nthat are responsible for requests handling.\n\nWhile using koa hakdi monkey patches `use` method.\n\n#### Basic usage:\n```javascript\nconst Koa = require('koa');\nconst { koaDI } = require('hekdi');\nconst app = new Koa();\n\nconst moduleToBootstrap = {\n  name: 'MainModule',\n  declarations: [\n    { name: 'ctrl', strategy: 'singleton', value: SomeClass },\n    { name: 'echo', \n      strategy: 'value', \n      value: async (ctx) =\u003e {\n         ctx.body = ctx.request.body;\n      }\n    }\n  ],\n  exports: '*'\n};\n\nkoaDI(moduleToBootstrap, app);\n// now di is already bootstrapped and ready to work. \n// In koa app you can reach di as `app.context.di`\n// In di you can get koa app as `App` dependency.\napp.use({\n  controller: 'ctrl', // if dependency is object\n  action: 'middleware', // you tell which of its methods will be called\n  params: [1, 2, 3] // also you can pass additional params to call if needed\n});\n\napp.use({ action: 'echo' }); \n// you can reach some function without class creation by passing only action\n// to `use` method\n\napp.use(async (ctx) =\u003e { // you still can pass function to `use` method\n  ctx.body = ctx.request.body;\n});\n\napp.listen(3000)\n```\n\n### Usage with router\nWhile using router the story is almost the same:\n```javascript \n'use strict';\n\nconst Koa = require('koa');\nconst Router = require('koa-router');\nconst bodyParser = require('koa-body-parser');\nconst { koaDI } = require('hekdi');\n\nconst app = new Koa();\nconst router = new Router();\n\nconst moduleToBootstrap = {\n  name: 'MainModule',\n  declarations: [\n    { name: 'ctrl', strategy: 'singleton', value: SomeClass },\n    { name: 'echo', \n      strategy: 'value', \n      value: async (ctx) =\u003e {\n         ctx.body = ctx.request.body;\n      }\n    }\n  ],\n  exports: '*'\n};\n\nkoaDI(moduleToBootstrap, app, router);\n\napp.use(bodyParser());\n\nrouter\n  .post(['/', '/test'], { action: 'echo'})\n  .get('/', {\n    controller: 'ctrl',\n    action: 'getHandler',\n    params: [1, 2, 3]\n  }).get('/test', async (ctx) =\u003e {\n    ctx.body = 'handled';\n  });\n\n  app\n    .use(router.routes())\n    .use(router.allowedMethods());\n\n  app.listen(3000);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FIvanProdaiko94%2Fhekdi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FIvanProdaiko94%2Fhekdi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FIvanProdaiko94%2Fhekdi/lists"}