0.0.7 init order fix, add proper README

This commit is contained in:
nitowa
2022-10-16 03:45:21 +02:00
parent 4395c00895
commit 2a9ded772e
3 changed files with 145 additions and 3 deletions
+143 -1
View File
@@ -1 +1,143 @@
Hello World # Overview
[![Build Status](https://drone.nitowa.xyz/api/badges/npm-packages/depents/status.svg)](https://drone.nitowa.xyz/npm-packages/depents)
[![Current Version](https://img.shields.io/npm/v/depents.svg)](https://www.npmjs.com/package/depents)
[![Weekly Downloads](https://img.shields.io/npm/dw/depents?color=important)](https://www.npmjs.com/package/depents)
[![License Type](https://img.shields.io/npm/l/depents?color=blueviolet)](https://gitea.nitowa.xyz/docs/depents/src/branch/master/LICENSE.md)
depents is a typescript dependency injection framework
# How to install
```
npm i depents
```
# Quickstart (TL;DR)
```typescript
import {Singleton, Inject, Injector} from 'dependjs'
@Singleton()
class AClass{
private A = 'a'
getA () {
return this.A
}
}
@Singleton()
class BClass{
@Inject(AClass)
private a: AClass
getA(){
return this.a.getA()
}
}
console.log(Injector.resolve(BClass).getA()) //"a"
```
# Working with interfaces as non-default injection tokens
As interfaces are not a runtime construct in javascript, classes have to be used in their place in order to work with injection resolution.
Consider this quick example:
File `MyModule/Interface.ts`
```typescript
export abstract class IComponent{
get: () => string
}
```
File `MyModule/Implementation.ts`
```typescript
import {IComponent} from 'Interface.ts'
@Singleton({
interface: IComponentB,
})
export class ComponentB implements IComponent{
get(): string {
return "Hello!"
}
}
```
File `Main.ts`
```typescript
import {IComponent} from 'MyModule/Interface.ts'
import {ComponentB} from 'Module/Implementation.ts'
ComponentB; //see Tree shaking pitfall below
Injector.resolve(IComponent).get()
```
# Tree shaking pitfall
TSC will attempt to exclude unused code in order to keep the compiled JS minimal. In the above example neither `Main.ts` nor `MyModule/Interface.ts` ever reference `MyModule/Implementation.ts` and it is therefore considered unused code. This will lead to the compilation output not containing the `ComponentB` class. To forcibly include `ComponentB`, it has to be referenced at least once - even if it is a senseless operation like in the above example.
# Initialization
This version of depents will simply call all constructors of classes marked as `Singleton` without arguments and it is therefore recommended that the user does not place initialization logic there. Alternatively, you may provide a function named `initialize` which will be called during Singleton creation.
An example:
```typescript
@Singleton()
export class Component{
private value: string
get(): string {
return this.value
}
initialize():void { //Called during object creation
this.value = "Hello!"
}
}
```
If your code requires objects to be initialized in a particular order, you may pass an optional `initializationPriority` parameter to `@Singleton`. The respective initialize operations will be called in order of `initializationPriority` from **lowest to highest**. If omitted, the default value is 0.
```typescript
@Singleton({
initializationPriority: 0
})
export class InitializedFirst{
private value: number
get(): number {
return this.value
}
initialize():void {
this.value = 1
}
}
@Singleton({
initializationPriority: 1
})
export class InitializedSecond{
@Inject(InitializedFirst)
private otherSingleton: InitializedFirst
private value: number
get(): number {
return this.value
}
initialize():void {
this.value = 1 + this.otherSingleton.get()
}
}
console.log(Injector.resolve(InitializedSecond).get()) //2
```
# [Full documentation](https://gitea.nitowa.xyz/docs/depents)
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "depents", "name": "depents",
"version": "0.0.6", "version": "0.0.7",
"description": "depents is a typescript dependency injector", "description": "depents is a typescript dependency injector",
"main": "./js/Index.js", "main": "./js/Index.js",
"repository": { "repository": {
+1 -1
View File
@@ -71,7 +71,7 @@ class _Injector {
private initializeSingletons = () => { private initializeSingletons = () => {
this.singletonDefinitions this.singletonDefinitions
.sort((a, b) => (b.initializationPriority ?? 0) - (a.initializationPriority ?? 0)) .sort((a, b) => (a.initializationPriority ?? 0) - (b.initializationPriority ?? 0))
.map(def => this.singletonObjects[def.ctor.name]) .map(def => this.singletonObjects[def.ctor.name])
.forEach(obj => obj.initialize ? obj.initialize() : undefined) .forEach(obj => obj.initialize ? obj.initialize() : undefined)
} }