# @halfbit/di

> Simple but extensible dependency injection for Javascript

Latest version **1.1.0** (published 2019-09-30) · ISC license · 0 weekly downloads

## Install

```sh
npm install @halfbit/di
pnpm add @halfbit/di
yarn add @halfbit/di
bun add @halfbit/di
```

## 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.1.0 |
| Published | 2019-09-30 |
| First published | 2019-05-22 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 20.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | Alexander Schulz |
| Maintainers | halfbit |
| Keywords | di, dependency injection, reflection, introspection |

## Links

- npm: https://www.npmjs.com/package/@halfbit/di
- Repository: https://github.com/tubersan/di.js
- Homepage: https://github.com/tubersan/di.js#readme
- Issues: https://github.com/tubersan/di.js/issues
- npm.io page: https://npm.io/package/@halfbit/di

## 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.1.0 (latest) — 2019-09-30
- 1.0.3 — 2019-05-24
- 1.0.2 — 2019-05-24
- 1.0.1 — 2019-05-23
- 1.0.0 — 2019-05-22

## README

# DI.js

[![npm (tag)](https://img.shields.io/npm/v/@halfbit/di/latest.svg)][npm-link]

DI.js is a simple yet extensible parameter dependency injection written in vanilla Javascript.

### Usage example

Providable resources are called `Parameter`, an evaluation context is called `Context`.
A `Context` can evaluate either a parameter name or the function which it will try to provide with all its parameters.
A most basic usage would look like this:
```js
import di from 'di';

let context = new di.Context();
context.addParameter('dog', { name: "Wooffers", bark: console.log.bind(window, 'Woof!') });

// No need for ugly ['dependency', function (dependency) {}] syntax
// Outputs 'Woof!' on the console!
context.evaluate(dog => dog.bark());
```
Under the hood, DI.js uses the functions `toString` method and some RegExp trickery to parse out all parameters.
It works with named, anonymous and arrow functions, and supports default as well as rest parameters.

A caveat is that parameters with functions with parameters themselves as default parameter will not work.

### Typing and custom adapters
DI.js offers type conversion via `Adapter`s.
An example would look like this:
```js
context.addAdapter('json', JSON.stringify);

// Returns '{"name":"Woofers"}'
context.evaluate("dog_json");
```

An `Adapter` has a type that it produces and at least one transforming function.

It can also have multiple transforming functions for different input types:
```js
context.addAdapter('str', String);
// Returns '[object Object]'
context.evaluate("dog_str");

// The third parameter is a fallback that is called if no matching input type is found
context.addAdapter('str', { 'object': JSON.stringify }, String);

// Returns '{"name":"Woofers"}'
context.evaluate("dog_str");
```

You might have noticed that the input type used here is `'object'` and that we never provided a type together with the `dog` `Parameter`.
We can actually specify our own type for `Parameter`s to enable for even fancier `Adapter`s:
```js
context.addParameter('dog', { name: "Wooffers", bark: console.log.bind(window, 'Woof!') }, 'dog');
context.addParameter('neighboursCat', { name: "Spotty", meow: console.log.bind(window, 'meow~') }, 'cat');

context.addAdapter('call', { 'dog': d => d.bark, 'cat': c => c.meow });

// 'Woof!'
context.evaluate("dog_call")();
// 'meow~'
context.evaluate("neighboursCat_call")();
```

The default type name that is used if no type conversion is specified (f.i. `context.evaluate('dog')`) is `'def'`.
A newly created `Context` will always have an `Adapter` defined for this type that simply returns the value, i.e. `a => a`.
However, if we override this `Adapter` then we can apply our own conversion, unbeknownst to the evaluated parameter or function:
```js
context.addAdapter('def', { 'cat': a => a.name, 'dog': a => a.name }, a => a);

// 'Wooffers'
context.evaluate("dog");
```


[npm-link]: https://www.npmjs.com/package/@halfbit/di

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