1.0.3 • Published 4 years ago

jslang-injector v1.0.3

Weekly downloads
2
License
MIT
Repository
github
Last release
4 years ago

jslang-injector

Simple JavaScript service injector for Browser or Node. Depends only on underscore. Compatible with IE 9 (no proxies).


Usage

const injector = require('jslang-injector');

// Define cache service:
function cacheService() {
    return {
        // ...
    };
}

// Define product service:
class ProductService {
    // ...
}

// Define pizza service:
class PizzaService {

    constructor(cacheService, productService) {
        // ...
    }

}
// Set inject options as static property:
PizzaService.__injectOptions = ['asProvider', (di) => new PizzaService(di.cacheService(), di.productService())];

// Define cheese pizza service:
class CheesePizzaService {

    constructor(pizzaService) {
        // ...
    }
    
    bake() {
        // ...
    }

}

let di = injector.create();

// Register cache service:
di.cacheService = injector.service(['asFunction', cacheService]);

// Register product service:
di.productService = injector.service(['asClass', ProductService]);

// Register pizza service:
di.pizzaService = injector.service(PizzaService); // inject options defined in static property `__injectOptions`

// Register cheese pizza service:
di.cheesePizzaService = injector.service(['asProvider', (di) => new CheesePizzaService(di.pizzaService())]);

return di.cheesePizzaService().bake();

Quick Guide

This simple package provides two resolve behaviors and four ways to define resolver.

Ways to define resolver

  1. Via function call:

    function cacheService() {
        return {
            // ...
        };
    }
    
    di.cacheService = injector.service(['asFunction', cacheService]);

    In this way di.cacheService() returns resolved instance of cacheService() call.

  2. Via class builder:

    class ProductService {
        // ...
    }
    
    di.productService = injector.service(['asClass', ProductService]);

    In this way di.productService() returns resolved instance of new ProductService() call.

  3. Via provider function:

    function namesService() {
        return {
            // ...
        };
    }
    
    di.namesService = injector.service(['asProvider', (di) => {
    
        // Any configuration here...
        const options = {};
    
        return namesService(di.cacheService(), options);
    }]);

    In this way di.namesService() returns resolved instance of user defined provider function call.

  4. Via static property:

    class PizzaService {
    }
    PizzaService.__injectOptions = ['asProvider', (di) => new PizzaService(di.cacheService(), di.productService())];
    
    di.pizzaService = injector.service(PizzaService);

    In this way di.pizzaService() returns resolved instance of PizzaService.__injectOptions instructions.

    Static injectOptions could be:

    1. A string: PizzaService.__injectOptions = 'asClass';.
    2. A short array: PizzaService.__injectOptions = ['asClass'];.
    3. A full array: PizzaService.__injectOptions = ['asClass', PizzaService];.

Resolve behaviors

  1. As service (injector.service(['asFunction', cacheService])) -- would be resolved once and cached for later usage.

  2. As factory (injector.factory(['asFunction', cacheService])) -- would be resolved on every di.cacheService() call.


ExpressJS middleware

Sample usage with express framework. In this case used middleware to bind req.di object.

const express = require('express');
const injector = require('jslang-injector');
const inject = require('jslang-injector/src/express/middleware/inject');

const CacheService = require('./path/to/cache-service');
const PizzaService = require('./path/to/pizza-service');

// Define available services bind handler:
inject.bindHandler = (req, serviceKey) => {
    switch (serviceKey) {
        case 'cache':
            req.di.cache = injector.service(CacheService);
            break;
        case 'pizza':
            req.di.pizza = injector.service(PizzaService);
            break;
        default:
            throw new Error(`Invalid service key: '${serviceKey}'!`);
    }
};


const app = express();

app.use('/hello-pizza', inject(['cache', 'pizza']), (req, res) => {
//                      ^ 'inject.bindHandler' will be called here

    // Now we can use services:
    let pizza = req.di.cache().get('pizza');
    if (!pizza) {
        pizza = req.di.pizza().bake();
    }
    return res.send(pizza.toHtml());
});