https://github.com/philip-bui/dagger
Javascript - Declarative dependency injection through IoC containers inspired by Java Dagger.
https://github.com/philip-bui/dagger
dependency-injection inversion-of-control javascript javascript-decorators react
Last synced: 4 months ago
JSON representation
Javascript - Declarative dependency injection through IoC containers inspired by Java Dagger.
- Host: GitHub
- URL: https://github.com/philip-bui/dagger
- Owner: philip-bui
- License: mit
- Created: 2020-02-29T06:13:47.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2023-01-06T02:36:10.000Z (about 3 years ago)
- Last Synced: 2025-04-14T12:14:51.397Z (10 months ago)
- Topics: dependency-injection, inversion-of-control, javascript, javascript-decorators, react
- Language: JavaScript
- Homepage:
- Size: 1.09 MB
- Stars: 4
- Watchers: 1
- Forks: 0
- Open Issues: 13
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Dagger
[](https://github.com/philip-bui/dagger/actions)
[](https://codecov.io/gh/philip-bui/dagger)
[](https://www.npmjs.com/package/@dagger-js/core)

Declarative dependency injection for Javascript, inspired by Java's [Dagger](https://dagger.dev/).
- **Declarative.** Dagger makes it easy to read and build complex applications.
Annotate dependencies, compose them and Dagger handles the wiring and injections.
- **Expressive.** Few simple decorators, yet powerful. Use a minimalistic API extended by rich options chaining.
- **Interoperable.** Adopt as little or as much dependency injection as you want.
Dagger helps improve class cohesion, loose coupling and testability.
## Installation
```bash
$ yarn add @dagger-js/core
```
Babel is used to compile decorators syntax and maintain compatibility with old JS environments. Add the [class](https://babeljs.io/docs/en/babel-plugin-proposal-decorators),
[properties](https://babeljs.io/docs/en/babel-plugin-proposal-class-properties) and
[parameter](https://www.npmjs.com/package/babel-plugin-parameter-decorator) decorator plugins.
```bash
$ yarn add -D @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties babel-plugin-parameter-decorator
```
```javascript
"plugins": [
["@babel/plugin-proposal-decorators", {"legacy": true}],
["@babel/plugin-proposal-class-properties", {"loose": true}],
"babel-plugin-parameter-decorator"
]
```
If you're using ESLint (and you probably should!), add the [babel-eslint](https://github.com/babel/babel-eslint)
parser to run on Babel compiled code.
```javascript
$ yarn add -D babel-eslint
```
```json
"eslintConfig": {
"parser": "babel-eslint",
"parserOptions": {
"ecmaFeatures": {
"legacyDecorators": true
}
},
}
```
## Usage
```javascript
import { Provides } from "@dagger-js/core";
@Provides
class FoodService {
getFood = () => ["Apple"];
}
```
```javascript
import { Singleton } from "@dagger-js/core";
@Singleton
class HeroService {
getHeroes = () => ["Saitama"];
}
```
Constructor Injection
```javascript
import { Inject, Named } from "@dagger-js/core";
@Inject
class HeroAcademcy {
constructor(@Named("HeroService") heroService, water, @Named("FoodService") foodService) {
this.heroes = heroService.getHeroes();
this.water = water;
this.food = foodService.getFood();
}
}
const heroAcademy = new HeroAcademcy(undefined, ["Water"]);
console.log(heroAcademy.heroes); // ["Saitama"];
console.log(heroAcademy.water); // ["Water"];
console.log(heroAcademy.food); // ["Apple"];
```
Property Injection
```javascript
import { Inject } from "@dagger-js/core";
import HeroService from "./HeroService";
class HeroAcademcy {
@Inject
heroService = HeroService; // Class
@Inject
HeroService = null;
@Inject.optional
godService = null;
@Inject.named("HeroService")
peopleService = null;
}
const heroAcademy = new HeroAcademcy();
console.log(heroAcademy.heroService.getHeroes()); // ["Saitama"];
console.log(heroAcademy.HeroService.getHeroes()); // ["Saitama"];
console.log(heroAcademy.godService); // null;
console.log(heroAcademy.peopleService.getHeroes()); // ["Saitama"];
```
## Advanced
Decorators are exported both capitalized and lower-case for convenience.
Extend your decorators with chainable options, chaining the same option twice will use the latter option.
### @Provides
Class decorator that declares a Class as Provider, creating new instances upon every injection.
- **lazy** - Instantiate instance lazily.
- Default: *false*
- **named(name)** - Register dependency under `name`.
- Default: *Class*
### @Singleton
Class decorator that declares a Class as Singleton, creating a single instance for every injection.
- **lazy** - Instantiate instance lazily.
- Default: *false*
- **named(name)** - Registers dependency under `name`.
- Default: *Class*
### @Inject
Class or property injection decorator that injects on constructor parameters, or ClassType or PropertyKey respectively.
- **computed** - Computed property.
- Default: *false*.
- **lazy** - Computed property until invoked once, then becomes a static value.
- Default: *false*.
- **optional** - Injects `undefined` if not found.
- Default: *false*
- **named(name)** - Injects dependency under `name`.
- Default: *Class*
> Note: Calling a constructor with provided values means Dagger won't override those values (unless `undefined`). This is by design.
### @Named(name)
Constructor parameter decorator used in conjunction with [@Inject](#@Inject).
- **optional** - Injects `undefined` if not found.
## License
Dagger is available under the MIT license. [See LICENSE](https://github.com/philip-bui/dagger/blob/master/LICENSE) for details.