simple-ioc

Simple Dependency Injection for node.js

npm install simple-ioc
12 downloads in the last day
331 downloads in the last week
1 510 downloads in the last month

simple-ioc

Simple Dependency Injection for node.js

Installation

npm install simple-ioc

Synopsis

An example of setting up the ioc

require( 'simple-ioc' )
    .setLogLevel( 3 )
    .register( 'settings', require( './configuration/settings' ) )
    .register( 'packageInfo', require( './package.json' ) )
    .register( 'amqp', require( 'amqp' ) )
    .autoRegister( './lib/' )
    .register( 'app', './handlers/itemQueryHandler.js' )
    .start( function( packageInfo, ioc ) {
        // ioc not used here but can be injected
        console.log( 'Application started, version:', packageInfo.version );
    } );

An example of an injected component, in this case './handlers/itemQueryHandler.js'

module.exports = function( settings, amqp ) {

    ...some code...

    return {
        ...something...
    };
};

Concepts

Files that are injectable normally looks like this:

module.exports = function( dependency1, dependency2... ) {
    // code    
};

Components that needs to be loaded asynchroniously can, by convension in the ioc, depend on a readyCallback, what ever that is used as the first parameter to this function will be loaded in the ioc.

module.exports = function( readyCallback ) {
    setTimeout( function() {
        readyCallback( { val: 4 } );
    }, 1000 );
};

Methods


setLogLevel( level )

Sets the minimum level of logs to cause an output, this only affects the ioc's logging.

NOTE: All FATAL errors also exists the application.

Arguments

  • level - minimum level

NOTE: Possible values:

  • 0: FATAL
  • 1: ERROR
  • 2: WARNING
  • 3: INFO
  • 4: DEBUG
  • 5: TRACE

Returns

The ioc

Example

ioc.setLogLevel( 1 ); // Will cause the ioc to only outputs FATAL and ERROR logs.

register( name, pathOrLoaded, lifecycleTransient )

Regsisters a component in the ioc.

Arguments

  • name - The name to identify the component when injecting
  • pathOrLoaded - Can either be a filepath, which will be required by the ioc and injected, all other types (objects, functions etc) will just be loaded into the ioc.
  • lifecycleTransient - Boolean, if set, the comopnent will be re-injected, when ever used as a dependency.

Returns

The ioc

Example

ioc
    .register( 'async', require( 'async' ) ) // Registers the async library as async
    .register( 'test', './test.js', true ); // Requires './test.js', and when used as dependency will be injected every time

registerRequired( name, required, lifecycleTransient )

Regsisters a function that will be injected when used as a dependency in the ioc.

Arguments

  • name - The name to identify the component when injecting
  • required - function that can be injected
  • lifecycleTransient - Boolean, if set, the comopnent will be re-injected, when ever used as a dependency.

Returns

The ioc

Example

ioc.registerRequired( 'myLibrary', require( 'my-library-in-node_modules' ) );

autoRegister( relativePath )

Searches the path for files that ends with '.js' and registers all with the filename (exluding .js) as name.

Arguments

  • relativePath - Path to folder or file.

Returns

The ioc

Example

ioc.autoRegister( './app' ); // Registers all files in the folder 'app'

start( callback )

Resolves and injects all registerd components that do not have a transient lifecycle.

Arguments

  • callback - Function that will be injected when all components are resolved. If setStartedCallback has been called, this function will also be injected.

Returns

The ioc

Example

ioc.start( function( async, myLibrary ) {
    // Code that uses async and myLibrary
} );

inject( fn )

Injects a function, similar to start, but will not resolve components that the function is not dependent of.

Arguments

  • fn - Function that will be injected.

Returns

The ioc

Example

ioc.inject( function( async, myLibrary ) {
    // Code that uses async and myLibrary
} );

reset()

Resets the ioc by removing all components, normally used in tests

Returns

The ioc

Example

ioc
    .register( 'test', { val: 1 } )
    .reset()
    .inject( function( test ) {
        // Will cause an fatal error, since test is no longer registered in the ioc.
    } );

setStartedCallback( fn )

Sets a function that will be injected after start is finished. If starts was called earlier, the function will be called directly.

Arguments

  • fn - Function that will be injected after start

Returns

The ioc

Example

ioc.setStartedCallback( function( test ) {
        console.log( test.toString() );
    } )
    .start();

setSettings( name, obj )

Sets settings that is registered and the ioc can access.

Arguments

  • name - Identifying name of settings
  • obj - The settings, an object.

Returns

The ioc

Example

ioc.setSettings( 'settings', { environment: 'test' } )
    .start( function( settings ) {
        console.log( settings.environment ); // Should output 'test'
    } );

conditionalAutoRegister( settingsKey, conditionalValue, path )

Reads settings, compares value to conditionalValue, if match perfoms a autoRegister

Arguments

  • settingsKey - String to search for in settings, .-notated
  • conditionalValue - value to compare against
  • path - Path to folder or file.

Returns

The ioc

Example

ioc.setSettings( 'settings', { environment: 'test' } )
    .conditionalAutoRegister( 'evironment', 'test', './lib' ); // Sould autoRegister './lib'

conditionalRegister( settingsKey, conditionalValue, name, pathOrLoaded, lifecycleTransient )

Reads settings, compares value to conditionalValue, if match perfoms a register

Arguments

  • settingsKey - String to search for in settings, .-notated
  • conditionalValue - value to compare against
  • name - The name to identify the component when injecting
  • pathOrLoaded - Can either be a filepath, which will be required by the ioc and injected, all other types (objects, functions etc) will just be loaded into the ioc.
  • lifecycleTransient - Boolean, if set, the comopnent will be re-injected, when ever used as a dependency.

Returns

The ioc

Example

ioc.setSettings( 'settings', { environment: 'test' } )
    .conditionalAutoRegister( 'evironment', 'test', 'some_component', require( 'some_component' ) ); // Sould register 'some_component'

conditionalRegister( settingsKey, conditionalValue, name, required, lifecycleTransient )

Reads settings, compares value to conditionalValue, if match perfoms a registerRequired

Arguments

  • settingsKey - String to search for in settings, .-notated
  • conditionalValue - value to compare against
  • name - The name to identify the component when injecting
  • required - function that can be injected
  • lifecycleTransient - Boolean, if set, the comopnent will be re-injected, when ever used as a dependency.

Returns

The ioc

Example

ioc.setSettings( 'settings', { environment: 'test' } )
    .conditionalRegisterRequired( 'evironment', 'test', 'some_component', function( settings ) { return 'test'; } ); // Sould register 'some_component'

setWaitingWarningTime( milliseconds )

Sets the amount of milliseconds the ioc waits for a component with a readyCallback to callback before it starts to warn

Arguments

  • milliseconds - amount of milliseconds

Returns

The ioc

Example

ioc.setWaitingWarningTime( 1000 ); // Will start to log warnings if components take more than 1 seconds to callback

wrap( name, wrapperName )

Wrap asynchronous component with name 'name' with the component with the name 'wrappedName' in order to measure for example its performance. The wrapped component can be either a function or an object. If it's a function it must have 'callback' as its last parameter. If it's an object each method of the object will be wrapped with the wrapper and these must each have 'callback' as their last parameter. 'wrappedName' is the name of a wrapper component that must only return a function with the following signature: function ( context, parameters, callback ).

context consists of

  • caller - the calling component
  • wrapped - the wrapped component
  • async - true/false (if the call was asyncronious)

The argument 'parameters' is an array with the parameters that is also sent to the wrapped function. The wrapper should not manipulate these but can read them.

The callback must be called once the wrapper has done its own work and must be called with a callback that will be called when the wrapped function has finished.

Arguments

  • name - the component to be wrapped (could be a function or object)
  • wrapperName - the wrapper that is registered in the ioc

Returns

The ioc

Example

timingWrapper.js:

module.exports = function () {
    return function ( context, parameters, callback ) {
        var start = Date.now();
        callback( function () {
            var totalTime = Date.now() - start;
            console.log( name, 'with parent', parentName, 'was called with params', parameters );
            console.log( 'it took', totalTime, 'ms');
        })
    }
}

asyncTask.js:

module.exports = function () {
    return function ( callback ) {
        setTimeout( callback, 100 )
    }
}

using the wrapper in the ioc:

ioc.autoRegister( './timingWrapper.js' )
    .autoRegister( './asyncTask.js' )
    .wrap( 'asyncTask', 'timingWrapper' )

wrap( settingsKey )

Registers werappers from settings

Arguments

  • settingsKey - The key to a settings-object which describes all wrappings

Returns

The ioc

Example

ioc.setSettings( 'settings', {
    wrapTheseComponents: {
        unwrapped: 'wrapper'
    }
} )
.register( 'unwrapped', './unwrapped.js' )
.register( 'wrapper', './wrapper.js' )
.wrapFromSettings( 'wrapTheseComponents' );

Release notes

2.2.0 - Wrapping

npm loves you