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",
|
||||
"version": "0.0.6",
|
||||
"version": "0.0.7",
|
||||
"description": "depents is a typescript dependency injector",
|
||||
"main": "./js/Index.js",
|
||||
"repository": {
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ class _Injector {
|
||||
|
||||
private initializeSingletons = () => {
|
||||
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])
|
||||
.forEach(obj => obj.initialize ? obj.initialize() : undefined)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user