assemblerjs
Version:
A general purpose Dependency Injection library for node and browser.
97 lines (66 loc) • 3.73 kB
Markdown
# assembler.js
A general purpose and zero-dependency [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection) library for node and browser.
   
---
`assembler.js` is inspired by both DIOD and Nestjs.
`assembler.js` name is a tribute to Gilles Deleuze and Felix Guattari concept of [_Agencement_](<https://fr.wikipedia.org/wiki/Agencement_(philosophie)>) (in french) that can be translated into [Assemblage](<https://en.wikipedia.org/wiki/Assemblage_(philosophy)>).
## Install
```sh
yarn add assemblerjs
```
```sh
npm install assemblerjs
```
## Usage
The main block of `assembler.js` is the **Assemblage**. It is created by decorating classes with the `` decorator. To keep everything type-safe, classes may implement `AbstractAssemblage` abstract class or define their own abstract class that extends it.
These abstract classes are used as identifiers to inject dependencies.
## Order of execution
Dependencies are registered and built recursively from the entry assemblage resolved by `Assembler.build`.
##### `onRegister`
Static hook called when registering the assemblage.
Other dependencies may or may not have been registered at this point, and dependency tree is not built yet.
##### `constructor`
Build the instance and requires an instance of each dependency passed to the constructor.
If the dependency is not a singleton a new instance is returned, meaning the same dependency required in another assemblage will be another object, as when using the `require` method of the `AssemblerContext` passed to hooks or injected by the `` decorator.
##### `onInit`
Called on every dependency when the dependency tree is ready.
Except for the entry assemblage (i.e. the one built on bootstrap by `Assembler.build`) the hook is called according to the latter.
The entry point assemblage is called last.
##### `onDispose`
Called when disposing the assembler via the `dispose` method injected by the `` decorator.
This will be called like the `onInit` method, walking through the dependency tree, except for the entry point assemblage, called last.
## Events
`assembler.js` provides an `EventManager` that can be subclassed by any assemblage.
Because all events **are forwarded by `AssemblerContext`** the `EventManager` is quite strict on which events can be broadcasted and they must be registered explicitly using the `events` property of the `AssemblageDefinition`. To avoid collision between events channels, user is strongly encouraged to create _strong_ channels names, e.g.: `com.domain.app.assemblage-name:init`.
```typescript
const prefix = 'com.domain.app.emitter-assemblage';
export enum EmitterAssemblageEvents {
Init = `${prefix}:init`,
}
export class EmitterAssemblage
extends EventManager
implements AbstractEventAssemblage
{
constructor() {
super();
}
public async onInit(): Promise<void> {
this.emit(EmitterAssemblageEvents.Init, true);
}
}
export class SubcriberAssemblage implements AbstractAssemblage {
constructor( private context: AssemblerContext) {
context.on(EmitterAssemblageEvents.Init, (value: boolean) => {
console.log(value); // true.
});
context.on('*', (value: boolean) => {
console.log(value); // true.
});
}
}
Assembler.build(SubcriberAssemblage);
```