1.0.6 • Published 4 months ago

di-nano v1.0.6

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
4 months ago

tests

GENERAL

An implementation of Dependency Injection pattern in a way, which enables its usages in a simplest way possible.

!NOTE DI decreases interdependence between modules, what leads to simplifying of tests writing and application logic.

Looks as follows:

// Module's dependencies listed as function parameters.

// user_controller.js - a SYNCHRONOUS module:
exports.UserController = ($conf, DataProvider) => { // <--- dependencies are in braces
  // ...
  router.get("/get-some-data", async (req, res, next) => {
    // ...
    const result = await DataProvider.getSomeData();
    // ...
  });
  return router;
}

// data_provider.js - an ASYNCHRONOUS module:
exports.DataProvider = async ($conf) => { // <--- dependencies are in braces
  // YOUR PREFERRED DB CONNECTOR
  return connector;
}

// server.js
const express = require("express");
const di      = require("di-nano");

di.init((ctx) => {
  ctx.registerOne(require(process.env.APP_CONFIG_PATH), "$conf");
  ctx.registerAll(require("./data_provider"));
  ctx.registerAll(require("./user_controller"));
  return ctx.invoke();
  // use an object destruction to get a list of specific modules here, when needed
}).then(({ $conf, UserController }) => { // <----
  const server = express();
  // ...
  server.use("/user", UserController);
  // ...
  server.listen($conf.server.port, () => {
    console.log(`Server is listening at ${$conf.server.port} port.`);
  });
});

EXAMPLE

A runnable working example could be found here.

USAGE

di-nano exposes next 4 functions to the end user:

  • init
  • registerAll
  • registerOne
  • invoke

    To define a dependency, create a function and export it under any name. Names MUST be unique among each other.

    1) SYNCHRONOUS DEPENDENCY:

    exports.SomeModule = () => { /**/ }

    2) ASYNCHRONOUS DEPENDENCY:

    exports.SomeModule = async () => { /**/ }
    
    // or
    
    exports.SomeModule = () => {
      // ...
      return new Promise((resolve, reject) => { /**/ });
    }

    !NOTE If a function returns a Promise, it will be automatically converted into async dependency.

    3) SETTING DEPENDENCIES LIST:

    To define module's dependencies, list them as typical function parameters, assuming they are defined in the same way, described already above. They can have a list of it's own dependencies too:

    exports.Module_A = (Module_B, Module_C, ... Module_N) => { /**/ }

    4) MULTIPLE DEPENDENCIES IN A SINGLE FILE:

    There is nothing special about this, since it is a plain Node.js export:

    exports.Module_A = (Module_C, Module_B) => { /**/ }
    exports.Module_B = (Module_C) => { /**/ }
    exports.Module_C = () => { /**/ }

    5) CONTEXT BUILD UP:

    const di = require("di-nano");
    
    di.init((ctx) => {
      ctx.registerAll(require("./some_module_1"));
      ctx.registerAll(require("./some_module_2"));
      return ctx.invoke();
    }).then((ctx) => {
      // ...
    });

    di.init resolves with an object which provides an access to all registered modules. An object destruction could be applied for receiving a list of specific modules:

    di.init((ctx) => {
      // ...
      return ctx.invoke();
    }).then(({ module_1, modul_2, module_n }) => {});

    !NOTE Before returning a result, ctx.invoke() will wait for all asynchronous dependencies to resolve.

    6) ANONYMOUS MODULE EXPORT:

    It is also possible to register an anonymous function or an object, but a name of a module MUST be set additionally. For this purpose serves registerOne:

    // module_a.js
    module.exports = () => { /**/ }
    
    // index.js
    di.init((ctx) => {
      ctx.registerOne(require("./module_a"), "MyModule");
      return ctx.invoke();
    }).then((ctx) => {
      // ...
    });

MODULE API

init(callback): Promise

/**
 * @param { Function } callback - A function to provide a context with.
 *
 * @returns Must return a result(Promise) of *** invoke *** call.
*/

registerAll(dependencies): undefined

/**
 * @param { Object } dependencies - An map of dependencies.
 *
 * @returns undefined.
*/

registerOne(dependency, name): undefined

/**
 * @param { Object } dependency - A single dependency map.
 * @param { String } name - A module name to set.
 *
 * @returns undefined.
*/

invoke(): Promise

/**
 * @returns A Promise, which resolves with DI context object.
*/
1.0.6

4 months ago

1.0.5

4 months ago

1.0.4

4 months ago

1.0.3

4 months ago

1.0.2

4 months ago

1.0.1

4 months ago

1.0.0

4 months ago