UNPKG

injektor

Version:

The simple dependency injection for Devebot

266 lines (198 loc) 7.12 kB
# injektor [![NPM](https://nodei.co/npm/injektor.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/injektor/) With injektor (and almost of dependency injection libraries), a developer can manage the service objects in a common "place" called **container** and doesn't care about assigning the dependent parameters to a service when it is invoked. ## Usage ### Installation Install injektor module: ```shell $ npm install --save injektor ``` ### Example In your program, create the container: ```javascript var Injektor = require('injektor'); var injektor = new Injektor(); ``` Register an object or define a service with some dependencies as follows: ```javascript injektor .registerObject('greeting', { greet: function() { return 'Hello world!'; } }); injektor .defineService('service1', function(fullname) { var self = fullname; this.sayHello = function(name) { console.log('Hello ' + name + ". I'm " + self); }; }) .registerObject('fullname', 'Computer'); injektor .defineService('service2', function() { this.sayWellcome = function(name) { console.log('Wellcome to ' + name); }; }); ``` Uses the `lookup()` method to get services or `invoke()` method to evaluate the services: ```javascript injektor.lookup('service1').sayHello('Ubuntu'); injektor.invoke(function (greeting, service1, service2) { console.log(greeting.greet()); console.log('\n'); service1.sayHello('Injektor'); service2.sayWellcome('Vietnam'); }); ``` The console will display the text below: ```plain Hello world! Hello Injektor. I'm Computer Wellcome to Vietnam ``` ## API ### Constructor #### `new Injektor(args)` `args` can be: * `args.detectCyclicDependencies` - enables/disables dependency cycle detection (default: `true`). * `args.nameResolvingStrictMode` - enables/disables name resolving strict mode (default: `false`). * `args.allowLookupDuplicateNames` - allows to return the fisrt matching name of duplicate short names (default: `false`). * `args.separator` - delimiter character (default: `/`). Example: ```javascript var Injektor = require('injektor'); var injektor = new Injektor({ separator: ':' }); ``` ### Methods #### `injektor.defineService(name, constructor, opts)` Method `defineService()` registers a service name with its constructor. The parameters include: * `name` - a case-sensitive string that presents the name of the defined service. The name must contain only letters, digits and underscore characters. It must start with a letter. * `constructor` - a function that is used with the `new` operator to create a new object. This object is cached by `injektor` and returned by `lookup()`. * `opts.scope` - a namespace of the scope in which this service/object belongs to. * `opts.exceptions` - a reference to an empty array that will collect thrown exceptions (if any) and prevent function crack. Method `defineService()` returns the `injektor` object itself. #### `injektor.registerObject(name, valueOrObject, opts)` Method `registerObject()` registers an object or a value (`number`, `boolean`, `null`,...) with its name. The parameters are similar to `defineService()` method, excepts the second parameter is a value or an object. It also returns the `injektor` object. #### `injektor.lookup(name, opts)` Method `lookup()` instantiates a service with injected dependencies into object, caches it for the next use, and returns it. This method contains the following parameters: * `name` - the name of a service or an object that should be retrieved. * `opts.scope` - a namespace of the scope in which this method finds the service or the object (default: undefined). * `opts.exceptions` - similar to `defineService()` method (default: undefined). #### `injektor.invoke(name_1, ..., name_n, callback)` Method `invoke()` retrieves an array of services or objects that are identified by `name_1, ..., name_n`, and push them as the parameters to the `callback` function. This method will return the `callback`'s returned value. ## Dependency Annotations ### Object schema annotation ```javascript var Injektor = require('injektor'); var injektor = new Injektor(); var MyResource = function(params) { params = params || {}; var fullname = params.fullname; var document = params.document; this.process = function(action) { console.log('The developer %s will %s the document %s', fullname, action, JSON.stringify(document)); }; }; MyResource.argumentSchema = { "type": "object", "properties": { "fullname": { "type": "string" }, "document": { "type": "object" } } }; injektor .defineService('myResource', MyResource) .registerObject('fullname', 'Peter Pan') .registerObject('document', { type: 'Book', content: 'Peter and Wendy' }); injektor.lookup('myResource').process('open'); ``` The console will display the following text: ```plain The developer Peter Pan will open the document {"type":"Book","content":"Peter and Wendy"} ``` ### Object properties annotation ```javascript var Injektor = require('injektor'); var injektor = new Injektor(); var MyResource = function(params) { params = params || {}; var fullname = params.fullname; var document = params.document; this.process = function(action) { console.log('The developer %s will %s the document %s', fullname, action, JSON.stringify(document)); }; }; MyResource.argumentProperties = [ "fullname", "document" ]; injektor .defineService('myResource', MyResource) .registerObject('fullname', 'Peter Pan') .registerObject('document', { type: 'Book', content: 'Peter and Wendy' }); injektor.lookup('myResource').process('open'); ``` The console will display the following text: ```plain The developer Peter Pan will open the document {"type":"Book","content":"Peter and Wendy"} ``` ### Explicit name annotation ```javascript var Injektor = require('injektor'); var injektor = new Injektor(); injektor .defineService('recipe', ['steps', 'object', function(steps, object) { steps = steps || []; this.action = function(name) { console.log('Hello, the instruction of %s is:', name); steps.forEach(function(step) { console.log(' - %s the %s', step, object); }); }; } ]) .registerObject('steps', [ 'clean', 'boil', 'peel', 'eat' ]) .registerObject('object', 'Eggs'); injektor .invoke(['recipe', function(rp) { rp.action('Peter Pan'); }]); ``` ### Implicit name annotation ```javascript var Injektor = require('injektor'); var injektor = new Injektor(); injektor .defineService('recipe', function(steps, object) { steps = steps || []; this.action = function(name) { console.log('Hello, the instruction of %s is:', name); steps.forEach(function(step) { console.log(' - %s the %s', step, object); }); }; }); injektor .registerObject('steps', [ 'clean', 'boil', 'peel', 'eat' ]) .registerObject('object', 'Eggs'); injektor.lookup('recipe').action('Peter Pan'); ``` ## License MIT