0.0.7 init order fix, add proper README
This commit is contained in:
@@ -1 +1,143 @@
|
|||||||
Hello World
|
# Overview
|
||||||
|
|
||||||
|
[](https://drone.nitowa.xyz/npm-packages/depents)
|
||||||
|
[](https://www.npmjs.com/package/depents)
|
||||||
|
[](https://www.npmjs.com/package/depents)
|
||||||
|
[](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
@@ -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
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user