refactor(web): dependency management (#2386)
This commit is contained in:
50
packages/utils/src/Domain/Dependency/DependencyContainer.ts
Normal file
50
packages/utils/src/Domain/Dependency/DependencyContainer.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { isNotUndefined } from '../Utils/Utils'
|
||||
import { isDeinitable } from './isDeinitable'
|
||||
|
||||
export class DependencyContainer {
|
||||
private factory = new Map<symbol, () => unknown>()
|
||||
private dependencies = new Map<symbol, unknown>()
|
||||
|
||||
public deinit() {
|
||||
this.factory.clear()
|
||||
|
||||
const deps = this.getAll()
|
||||
for (const dep of deps) {
|
||||
if (isDeinitable(dep)) {
|
||||
dep.deinit()
|
||||
}
|
||||
}
|
||||
|
||||
this.dependencies.clear()
|
||||
}
|
||||
|
||||
public getAll(): unknown[] {
|
||||
return Array.from(this.dependencies.values()).filter(isNotUndefined)
|
||||
}
|
||||
|
||||
public bind<T>(sym: symbol, maker: () => T) {
|
||||
this.factory.set(sym, maker)
|
||||
}
|
||||
|
||||
public get<T>(sym: symbol): T {
|
||||
const dep = this.dependencies.get(sym)
|
||||
if (dep) {
|
||||
return dep as T
|
||||
}
|
||||
|
||||
const maker = this.factory.get(sym)
|
||||
if (!maker) {
|
||||
throw new Error(`No dependency maker found for ${sym.toString()}`)
|
||||
}
|
||||
|
||||
const instance = maker()
|
||||
if (!instance) {
|
||||
/** Could be optional */
|
||||
return undefined as T
|
||||
}
|
||||
|
||||
this.dependencies.set(sym, instance)
|
||||
|
||||
return instance as T
|
||||
}
|
||||
}
|
||||
14
packages/utils/src/Domain/Dependency/isDeinitable.ts
Normal file
14
packages/utils/src/Domain/Dependency/isDeinitable.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
export function isDeinitable(service: unknown): service is { deinit(): void } {
|
||||
if (!service) {
|
||||
throw new Error('Service is undefined')
|
||||
}
|
||||
return typeof (service as { deinit(): void }).deinit === 'function'
|
||||
}
|
||||
|
||||
export function canBlockDeinit(service: unknown): service is { blockDeinit(): Promise<void> } {
|
||||
if (!service) {
|
||||
throw new Error('Service is undefined')
|
||||
}
|
||||
|
||||
return typeof (service as { blockDeinit(): Promise<void> }).blockDeinit === 'function'
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
export * from './Date/DateUtils'
|
||||
export * from './Deferred/Deferred'
|
||||
export * from './Dependency/DependencyContainer'
|
||||
export * from './Dependency/isDeinitable'
|
||||
export * from './Logger/Logger'
|
||||
export * from './Logger/LoggerInterface'
|
||||
export * from './Logger/LogLevel'
|
||||
|
||||
Reference in New Issue
Block a user