https://github.com/ssube/noicejs
extremely thin async dependency injection
https://github.com/ssube/noicejs
async dependency-injection dependency-injection-container di guice service-locator typescript
Last synced: 6 months ago
JSON representation
extremely thin async dependency injection
- Host: GitHub
- URL: https://github.com/ssube/noicejs
- Owner: ssube
- License: mit
- Created: 2016-02-08T18:27:52.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2025-03-20T06:35:33.000Z (7 months ago)
- Last Synced: 2025-04-09T22:18:15.443Z (6 months ago)
- Topics: async, dependency-injection, dependency-injection-container, di, guice, service-locator, typescript
- Language: TypeScript
- Homepage: https://ssube.github.io/noicejs/
- Size: 2.19 MB
- Stars: 17
- Watchers: 2
- Forks: 6
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.md
Awesome Lists containing this project
README
# noicejs
Extremely thin, async dependency injection, now with
[a getting started guide](https://ssube.github.io/noicejs/getting-started).Inspired by [Google's Guice library](https://github.com/google/guice) and written in
[Typescript](https://www.typescriptlang.org/).## Features
- async dependency resolution
- constructor and property injection
- modular containers with inheritance
- named dependencies using strings or unique symbols
- typed errors
- typescript typedefs
- zero runtime dependencies, bundled or otherwise
- extensive test coverage## Contents
- [noicejs](#noicejs)
- [Features](#features)
- [Contents](#contents)
- [Status](#status)
- [Releases](#releases)
- [Usage](#usage)
- [Build](#build)
- [License](#license)## Status
[](https://git.apextoaster.com/ssube/noicejs/commits/master)
[](https://sonarcloud.io/dashboard?id=ssube_noicejs)
[](https://codecov.io/gh/ssube/noicejs)
[](https://github.com/ssube/noicejs/blob/master/LICENSE.md)
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fssube%2Fnoicejs?ref=badge_shield)[](https://github.com/ssube/noicejs/issues?q=is%3Aopen+is%3Aissue+label%3Atype%2Fbug)
[](https://github.com/ssube/noicejs/issues?q=is%3Aopen+is%3Aissue)
[](https://github.com/ssube/noicejs/issues?q=is%3Aissue+is%3Aclosed)[](https://renovatebot.com)
[](https://david-dm.org/ssube/noicejs)
[](https://david-dm.org/ssube/noicejs?type=dev)
[](https://snyk.io/test/github/ssube/noicejs)[](https://codeclimate.com/github/ssube/noicejs/maintainability)
[](https://codeclimate.com/github/ssube/noicejs/trends/technical_debt)
[](https://codeclimate.com/github/ssube/noicejs/issues)
[](https://lgtm.com/projects/g/ssube/noicejs/context:javascript)
[](https://lgtm.com/projects/g/ssube/noicejs/alerts/)## Releases
- 3.x versions are compatible with Node 12+
- 4.x versions are compatible with Node 16+[](https://github.com/ssube/noicejs/releases)
[](https://github.com/ssube/noicejs/releases)
[](https://github.com/ssube/noicejs/compare/v3.0.1...master)[](https://www.npmjs.com/package/noicejs)
[](https://www.npmjs.com/package/noicejs)
[](https://www.npmjs.com/package/noicejs)## Usage
Consider a `Server` class that needs to fetch data from the `Cache` and `Filesystem`, but doesn't know (or need to
know) how those are implemented. The following example is [also part of the unit tests](./test/examples/TestReadme.ts).```typescript
import { LocalModule } from './local';
import { NetworkModule } from './network';class Cache {
public get(path: string, ttl: number, fallback: () => Promise): Promise {
/* ... */
}
}class Filesystem {
public get(path: string): Promise {
/* ... */
}
}/**
* Constructors, strings, and symbols are supported. Symbols are
* preferred, as the most unique, but names can be convenient.
*/
@Inject(Cache.name.toLowerCase(), Filesystem.name.toLowerCase())
class Server {
protected readonly cache: Cache;
protected readonly filesystem: Filesystem;
protected readonly ttl: number;constructor(options) {
this.cache = options.cache;
this.filesystem = options.filesystem;
this.ttl = defaultTo(options.ttl, 0);
}get(path: string) {
return options.cache.get(path, this.ttl, () => options.filesystem.get(path));
}
}const TEST_TTL = 60;
function module() {
if (process.env['DEBUG'] === 'TRUE') {
return new LocalModule();
} else {
return new NetworkModule();
}
}async function main() {
const container = Container.from(module());
await container.configure();const server = await container.create(Server, {
/* cache and filesystem are found and injected by container */
ttl: TEST_TTL,
});/* server.cache.get and server.filesystem.get will be called in order */
const result = await server.get('some/file');
}
```noicejs will collect dependencies from the decorated constructor and any superclasses, find a provider for each
injected dependency, and asynchronously resolve them before calling the constructor. Any extra parameters are passed
on to the original constructor, along with the container and resolved dependencies.## Build
To build a bundle and run tests:
```shell
> makeyarn
yarn install v1.17.3
[1/4] Resolving packages...
success Already up-to-date.
Done in 0.20s.
/home/ssube/code/ssube/noicejs//node_modules/.bin/rollup --config /home/ssube/code/ssube/noicejs//config/rollup.jssrc/index.ts, test/harness.ts, test/**/Test*.ts → out/...
...
created out/ in 3.3s
/home/ssube/code/ssube/noicejs//node_modules/.bin/api-extractor run --config /home/ssube/code/ssube/noicejs//config/api-extractor.json --local -vapi-extractor 7.3.8 - https://api-extractor.com/
...API Extractor completed successfully
Success!
```## License
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fssube%2Fnoicejs?ref=badge_large)