Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

bottlejs

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bottlejs

A powerful, extensible dependency injection micro container

  • 0.7.2
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
25K
decreased by-11.3%
Maintainers
1
Weekly downloads
 
Created
Source

BottleJS

BottleJS Build Status

A powerful, extensible dependency injection micro container

Introduction

BottleJS is a tiny yet powerful dependency injection container. It features lazy loading, middleware hooks, decorators and a clean api inspired by the AngularJS Module API and the simple PHP library Pimple. You'll like BottleJS if you enjoy:

  • building a stack from components rather than a kitchen-sink framework.
  • uncoupled objects and dependency injection.
  • an API that makes sense.
  • lazily loaded objects.
  • trying cool stuff :smile:

Browser Support

BottleJS supports IE9+ and other ECMAScript 5 compliant browsers.

Installation

BottleJS can be used in a browser or in a nodejs app. It can be installed via bower or npm:

$ bower install bottlejs
$ npm install bottlejs

Simple Example

The simplest recipe to get started with is Bottle#service. Say you have a constructor for a service object:

var Beer = function() { /* A beer service, :yum: */ };

You can register the constructor with Bottle#service:

var bottle = new Bottle();
bottle.service('Beer', Beer);

Later, when you need the constructed service, you just access the Beer property like this:

bottle.container.Beer;

A lot happened behind the scenes:

  1. Bottle created a provider containing a factory function when you registered the Beer service.
  2. When the bottle.container.Beer property was accessed, Bottle looked up the provider and executed the factory to build and return the Beer service.
  3. The provider and factory were deleted, and the bottle.container.Beer property was set to be the Beer service instance. Accessing bottle.container.Beer in the future becomes a simple property lookup.

Injecting Dependencies

The above example is simple. But, what if the Beer service had dependencies? For eample:

var Barley = function() {};
var Hops = function() {};
var Water = function() {};
var Beer = function(barley, hops, water) { /* A beer service, :yum: */ };

You can register services with Bottle#service and include dependencies like this:

var bottle = new Bottle();
bottle.service('Barley', Barley);
bottle.service('Hops', Hops);
bottle.service('Water', Water);
bottle.service('Beer', Beer, 'Barley', 'Hops', 'Water');

Now, when you access bottle.container.Beer, Bottle will lazily load all of the dependencies and inject them into your Beer service before returning it.

Service Factory

If you need more complex logic when generating a service, you can register a factory instead. A factory function receives the container as an argument, and should return your constructed service:

var bottle = new Bottle();
bottle.service('Barley', Barley);
bottle.service('Hops', Hops);
bottle.service('Water', Water);
bottle.factory('Beer', function(container) {
    var barley = container.Barley;
    var hops = container.Hops;
    var water = container.Water;

    barley.halved();
    hops.doubled();
    water.spring();
    return new Beer(barley, hops, water);
});

Service Provider

This is the meat of the Bottle library. The above methods Bottle#service and Bottle#factory are just shorthand for the provider function. You usually can get by with the simple functions above, but if you really need more granular control of your services in different environments, regiser them as a provider. To use it, pass a constructor for the provider that exposes a $get function. The $get function is used as a factory to build your service.

var bottle = new Bottle();
bottle.service('Barley', Barley);
bottle.service('Hops', Hops);
bottle.service('Water', Water);
bottle.provider('Beer', function() {
    // This environment may not support water.
    // We should polyfill it.
    if (waterNotSupported) {
        Beer.pollyfillWater();
    }

    // this is the service factory.
    this.$get = function(container) {
        var barley = container.Barley;
        var hops = container.Hops;
        var water = container.Water;

        barley.halved();
        hops.doubled();
        water.spring();
        return new Beer(barley, hops, water);
    };
});

Decorators

Bottle supports injecting decorators into the provider pipeline with the Bottle#decorator method. Bottle decorators are just simple functions that intercept a service in the provider phase after it has been created, but before it is accessed for the first time. The function should return the service, or another object to be used as the service instead.

var bottle = new Bottle();
bottle.service('Beer', Beer);
bottle.service('Wine', Wine);
bottle.decorator(function(service) {
    // this decorator will be run for both Beer and Wine services.
    service.stayCold();
    return service;
});

bottle.decorator('Wine', function(wine) {
    // this decorator will only affect the Wine service.
    wine.unCork();
    return wine;
});

Middleware

Bottle middleware are similar to decorators, but they are executed every time a service is accessed from the container. They are passed the service instance and a next function:

var bottle = new Bottle();
bottle.service('Beer', Beer);
bottle.middleware(function(service, next) {
    // this middleware will be executed for all services
    console.log('A service was accessed!');
    next();
});

bottle.middleware('Beer', function(beer, next) {
    // this middleware will only affect the Beer service.
    console.log('Beer?  Nice.  Tip your bartender...');
    next();
});

Nested Bottles

Bottle will generate nested containers if dot notation is used in the service name. A sub container will be created for you based on the name given:

var bottle = new Bottle();
var IPA = function() {};
bottle.service('Beer.IPA', IPA);
bottle.container.Beer; // this is a new Bottle.container object
bottle.container.Beer.IPA; // the service

API

Bottle

pop([name])

Used to get an instance of bottle. If a name is passed, bottle will return the same instance. Calling the Bottle constructor as a function will call and return return Bottle.pop, so Bottle.pop('Soda') === Bottle('pop')

ParamTypeDetails
name
(optional)
The name of the bottle. If passed, bottle will store the instance internally and return the same instance if Bottle.pop is subsequently called with the same name.

Bottle.prototype

constant(name, value)

Used to add a read only value to the container.

ParamTypeDetails
nameStringThe name of the constant. Must be unique to each Bottle instance.
valueMixedA value that will be defined as enumerable, but not writable.
decorator(name, func)

Used to register a decorator function that the provider will use to modify your services at creation time.

ParamTypeDetails
name
(optional)
StringThe name of the service this decorator will affect. Will run for all services if not passed.
funcFunctionA function that will accept the service as the first parameter. Should return the service, or a new object to be used as the service.
defer(func)

Register a function to be executed only when Bottle#resolve is called.

ParamTypeDetails
funcFunctionA function to be called later. Will be passed a value given to Bottle#resolve.
digest(services)

Immediately instantiate an array of services and return their instances in the order of the array of instances.

ParamTypeDetails
servicesArrayArray of services that should be instantiated.
factory(name, Factory)

Used to register a service factory

ParamTypeDetails
nameStringThe name of the service. Must be unique to each Bottle instance.
FactoryFunctionA function that should return the service object. Will only be called once; the Service will be a singleton. Gets passed an instance of the container to allow dependency injection when creating the service.
middleware(name, func)

Used to register a middleware function. This function will be executed every time the service is accessed.

ParamTypeDetails
name
(optional)
StringThe name of the service for which this middleware will be called. Will run for all services if not passed.
funcFunctionA function that will accept the service as the first parameter, and a next function as the second parameter. Should execute next() to allow other middleware in the stack to execute.
provider(name, Provider)

Used to register a service provider

ParamTypeDetails
nameStringThe name of the service. Must be unique to each Bottle instance.
ProviderFunctionA constructor function that will be instantiated as a singleton. Should expose a function called $get that will be used as a factory to instantiate the service.
register(Obj)
container.$register(Obj)

Used to register a service, factory, provider, or value based on properties of the Obj. bottle.container.$register is an alias of bottle.register; this allows factories and providers to register multiple services on the container without needing access to the bottle instance itself.

ParamTypeDetails
ObjObject|FunctionAn object or constructor with one of several properties:
  • Obj.$namerequired — the name used to register the object
  • Obj.$typeoptional — the method used to register the object. Defaults to 'service' in which case the Obj will be treated as a constructor. Valid types are: 'service', 'factory', 'provider', 'value'
  • Obj.$injectoptional — If Obj.$type is 'service', this property can be a string name or an array of names of dependencies to inject into the constructor.
    E.g. Obj.$inject = ['dep1', 'dep2'];
resolve(data)

Execute any deferred functions registered by Bottle#defer.

ParamTypeDetails
data
(optional)
MixedValue to be passed to each deferred function as the first parameter.
service(name, Constructor [, dependency [, ...]])

Used to register a service constructor

ParamTypeDetails
nameStringThe name of the service. Must be unique to each Bottle instance.
ConstructorFunctionA constructor function that will be instantiated as a singleton.
dependency
(optional)
StringAn optional name for a dependency to be passed to the constructor. A dependency will be passed to the constructor for each name passed to Bottle#service in the order they are listed.
value(name, val)

Used to add an arbitrary value to the container.

ParamTypeDetails
nameStringThe name of the value. Must be unique to each Bottle instance.
valMixedA value that will be defined as enumerable, but not writable.

Keywords

FAQs

Package last updated on 26 Dec 2014

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc