1.0.1 • Published 8 years ago

simple-node-di v1.0.1

Weekly downloads
1
License
ISC
Repository
bitbucket
Last release
8 years ago

Simple Dependency Injection Utility for Node.js

Usage

1. Register the dependencies

const di = require("simple-node-di");


// Constant

di.register("port", 3001, di.types.CONST);
di.register("config", { requestTimeout: 1000 }, di.types.CONST);


// Factory function (arrow)

const mergeConfig_arrow = (port, config) => Object.assign(config, { port });
di.register("appConfig", mergeConfig_arrow, di.types.FACTORY);


// Factory function (old-style function)

const mergeConfig_func = function (port, config) {
  return Object.assign(config, { port });
};
di.register("appConfigFunc", mergeConfig_func, di.types.FACTORY);


// Class

class MyClass {
  constructor (port, appConfig) {
    this.port = port;
    this.appConfig = appConfig;
  }
}
di.register("myClass", MyClass, di.types.CLASS);

2. Inject the dependencies

const di = require("simple-node-di");

const port = di.inject("port"); // 3001
const appConfig = di.inject("appConfig"); // { requestTimeout: 1000, port: 3001 }
const instance = di.inject("myClass");

instance instanceof MyClass; // true
instance.port; // 3001
instance.appConfig; // { requestTimeout: 1000, port: 3001 }

Types

  • CLASS
    • The DI will inject an instance of the provided class.
    • Constructor function is optional.
    • Arguments of the constructor function will be injected by their names.
  • CONST
    • The DI will inject the exact value/object registered.
  • FACTORY
    • The DI will inject an object/value returned from the registered function.
    • Both the function keyword or an arrow function is supported.
    • Arguments of the factory function will be injected by their names.

API

di.register(name, factory, type, options)

Registers a dependency.

  • name: {String} dependency name
  • factory: {function|class|Object|*} the dependency (factory function, class or the constant value)
  • type: {String} dependency type (di.types.*)
  • options: {Object} Options

Options

  • options.static {bool} If true, any registrations of an already-registered dependency will be ignored.
  • options.dependencies {Array} List of the registered dependency's sub-dependencies.

di.inject(name)

Injects a dependency.

  • name: {String} dependency name

Dependencies of a registered factory function/class

Explicit

  • The largest priority have the sub-dependencies provided in the registration options: di.register("cls", MyClass, di.types.CLASS, { dependencies: ["config", "model"] });

  • Otherwise, the factory function/class is checked for a dependencies property:

// Class
class Clz {
  ...
}

module.exports = Clz;
module.exports.dependencies = ["config"];

// Factory function
const factory = (c, m) => {
  ...
}
factory.dependencies = ["config", "model"];

Implicit If no explicit definition of the registered dependency's sub-dependencies was found, simple-node-di parses the factory function or the class' constructor for its arguments. To successfully inject a sub-dependency, an argument's name has to match a registered dependency's name:

di.register("config", { ... }, di.types.CONST);

// Class
class Clz {
  constructor(config) {} // The argument will be injected automatically
}

// Factory function
const factory = (config) => { // The argument will be injected automatically
  ...
}

Implicit injection also supports subclasses. When searching for dependencies, a "tree" of the super-classes is traversed until the first constructor is found:

// Parent class
class Parent {
  constructor (config) {} // Parent class' constructor
}

// Child class
class Clz extends Parent {} // No constructor

di.register("config", { ... }, di.types.CONST);
di.register("cls", Clz, di.types.CLASS);
1.0.1

8 years ago

1.0.0

8 years ago