npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

node-di-container

v0.1.7

Published

Simple DI container

Downloads

11

Readme

node-di

Build Status Coverage Status

Simple AngularJS inspired DI container for node.js

Getting started

Installation

npm install node-di-container

Example

var di = require('node-di-container');

// Some app-specific configuration
var config = require('./config');

// Creates an UserRepository based on the configuration
var UserRepositoryProvider = require('./userRepositoryProvider');

// Uses an UserRepository
var UserManager = require('./userManager');

// Registering the dependencies
var container = di.container()
    .value('config', config)
    .service('userRepositoryProvider', UserRepositoryProvider)
    .factory('userRepository', function(userRepositoryProvider) {
        return userRepositoryProvider.getRepository();
    })
    .service('userManager', UserManager);

var injector = di.injector(container);

// Invoking a function with some dependencies
injector.invoke(function (userManager) {
    ...
});

Basic concepts

Creating a DI container

The dependency container is the central repository where the dependencies are stored and later resolved from.

To create a DI container:

var di = require('node-di-container');

var container = di.container();

To create a DI container that caches the resolved dependencies:

var container = di.cacheableContainer();

Containers can be chained, creating scopes that help better organize dependencies:

// Register some global dependencies that will be available to all consumers ...
var global = di.container();

// The scoped container 'sees' its own dependencies and those registered on the parent container (global). All dependencies registered on this container are not available to the parent container though.
var scoped = di.container(global);

// One more level of isolation ...
var local = di.container(scoped);

Resolving dependencies always starts from the current container and moving up the chain of parent containers up until it is resolved or there the top most container is reached. Parent containers have no access to the child containers.

Using multiple levels of containers allows parent dependencies to be overridden without actually breaking the parent container and its consumers. To override a parent dependency simply register the new one using the same key.

Registering dependencies

Dependencies are registered and later resolved by a key. The key is a string that uniquely identifies the dependency in the context of the container.

Depending on how the dependencies are registered there are

Values

Values can be any valid JavaScript object and are resolved to the value itself:

container.value('myVal', 123);

Services

Services are defined by a constructor function. This dependency resolves to the result of the constructor function - usually an object instance.

container.service('myService', MyService);

The constructor function itself may have dependencies that will be resolved before the invocation. For more information how the define dependencies see Dependency annotation.

Factory

This dependency resolves to the result of the factory function.

container.factory('z', function(x, y){
    return (x + y);
});

The function itself may have dependencies that will be resolved on invocation. For more information how the define dependencies see Dependency annotation.

Dependency annotation

Functions with dependencies are invoked vie the injector. These functions need to be annotated so that the injector knows what dependencies to inject into the function.

There are three ways of annotating functions:

  • Implicitly from the function parameters names
function f(foo, bar) {
    ...
}
  • Using the $inject annotation
function f(arg1, arg2) {
    // arg1 is resolved to foo
    // arg2 is resolved to bar
}

f.$inject = ['foo', 'bar'];
  • Using the inline array annotation:

When registering a dependency:

container.service('myService', ['foo', 'bar', MyService]);
container.service('myService', ['foo', 'bar', MyService]);

Invoking a function:

injector.invoke(['foo', 'bar', f])
injector.createInstance(['foo', 'bar', MyObject]);

Resolving dependencies

To invoke a function or create an object instance with dependencies use an injector:

var di = require('node-di-container');
var container = di.container()
                    .value('foo', 1)
                    .value('bar', 2);

var injector = di.injector(container);

For more information how the define dependencies see Dependency annotation.

Invoking a function with dependencies

function foo(foo, bar) {
    return (foo + bar);
}

var result = injector.invoke(foo);

Invoking a constructor function with dependencies

function MyService(foo, bar) {
    ...
}

var myService = injector.createInstance(MyService);

Resolving dependencies by key

Sometimes it is convenient to simply get any dependency like this:

var config = injector.get('config');

API

Top-level API

di

di is the entry point to the node-di-container library:

var di = require('node-di-container');
di.container([parentContainer])

Creates a dependency container.

Parameters:

  • parentContainer: (optional)

Returns:

di.cacheableContainer([parentContainer])

Creates a dependency container that cache the dependencies registered as a service or factory.

Parameters:

  • parentContainer: (optional)

Returns:

di.injector(container)
Parameters:
  • container: the dependency container to resolve the dependencies from.
Returns:

Container API

The object created from di.container() or di.cacheableContainer();

container.value(key, value)

Parameters:
  • key (String): a string value that uniquely identifies the dependency in this container;
  • value (Any): the value this dependency is resolved to.
Returns
  • the container object

container.service(key, constructor)

Parameters:
  • key (String): a string value that uniquely identifies the dependency in this container;
  • constuctor (Function|Array): the constructor function to be invoked on resolving the dependency. The function can have dependencies itself that will be resolved prior to its invocation. For more information on how to annotate a function with dependencies please see Dependency annotation.
Returns
  • the container object

container.factory(key, fn)

Parameters:
  • key (String): a string value that uniquely identifies the dependency in this container;
  • fn (Function|Array): the function to be invoked on resolving the dependency. The function can have dependencies itself that will be resolved prior to its invocation. For more information on how to annotate a function with dependencies please see Dependency annotation.
Returns
  • the container object.

container.resolve(key)

Returns the resolved dependency by the given key.

Parameters
  • key (String): the key of the dependency to be resolved.
Returns
  • the resolved dependency.
Example
var config = container.get('config');

Injector API

The object created from di.injector().

injector.invoke(fn)

Parameters
  • fn (Function|Array): the function to be invoked. For more information on how to annotate a function with dependencies please see Dependency annotation.
Returns
  • the result of the invocation of the given function fn
Notes

Actual function invocation:

fn.apply(null, [dependencies])

injector.createInstance(constructor)

Parameters
  • constructor (Function|Array): the constructor function to be invoked. For more information on how to annotate a function with dependencies please see Dependency annotation.
Returns
  • the result of the invocation of the given constructor function constructor.
Notes

Objects are created with Object.create() like this:

var obj = Object.create(constructor.prototype);
constructor.apply(obj, [dependencies]);

injector.get(key)

Returns the resolved dependency by the given key.

Parameters
  • key (string): the key of the dependency to be resolved.
Returns
  • the resolved dependency.
Notes

This is similar to container.resolve(key).

Example
var config = injector.get('config');