simple-node-di v1.0.1
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);