# jslang-injector

> Simple JavaScript service injector.

Latest version **1.0.3** (published 2020-07-16) · MIT license · 0 weekly downloads

## Install

```sh
npm install jslang-injector
pnpm add jslang-injector
yarn add jslang-injector
bun add jslang-injector
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.3 |
| Published | 2020-07-16 |
| First published | 2019-07-11 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 1 |
| Unpacked size | 10.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | Lev Nazarenko |
| Maintainers | mightydes |
| Keywords | inject, injector, di, dependency injection |

## Links

- npm: https://www.npmjs.com/package/jslang-injector
- Repository: https://github.com/mightydes/jslang-injector
- Issues: https://github.com/mightydes/jslang-injector/issues
- npm.io page: https://npm.io/package/jslang-injector

## Dependencies (1)

- [underscore](https://npm.io/package/underscore.md) ^1.8

## Alternatives

- [memory-cache](https://npm.io/package/memory-cache.md) — 795.0K weekly downloads
- [@httptoolkit/proxy-agent](https://npm.io/package/@httptoolkit/proxy-agent.md) — 11.2K weekly downloads
- [express-cache-controller](https://npm.io/package/express-cache-controller.md) — 5.3K weekly downloads
- [http-cache-middleware](https://npm.io/package/http-cache-middleware.md) — 4.5K weekly downloads
- [cache2](https://npm.io/package/cache2.md) — 1.5K weekly downloads

## Recent versions

- 1.0.3 (latest) — 2020-07-16
- 1.0.2 — 2020-07-15
- 1.0.1 — 2019-07-12
- 1.0.0 — 2019-07-11

## README

# jslang-injector

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

---
## Usage

```js
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:

    ```js
    function cacheService() {
        return {
            // ...
        };
    }

    di.cacheService = injector.service(['asFunction', cacheService]);
    ```

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

1.  Via class builder:

    ```js
    class ProductService {
        // ...
    }

    di.productService = injector.service(['asClass', ProductService]);
    ```

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

1.  Via provider function:

    ```js
    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.

1.  Via static property:

    ```js
    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';`.
    1.  A short array: `PizzaService.__injectOptions = ['asClass'];`.
    1.  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.

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

---
## ExpressJS middleware

Sample usage with [express](http://expressjs.com/) framework.
In this case used middleware to bind `req.di` object.

```js
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());
});

```

---
_Source: https://npm.io/package/jslang-injector · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
