Files
Typescript-Dependency-Manager/dependency-manager.ts
2024-05-31 14:50:46 +02:00

54 lines
1.5 KiB
TypeScript

type Provider<T> = (manager: DependencyManager) => Promise<T> | T;
type ClassType<T> = new () => T;
// deno-lint-ignore no-explicit-any
type ModuleIdentifier = any;
type Modules = Map<ModuleIdentifier, {
// deno-lint-ignore no-explicit-any
provider: Provider<any>;
// deno-lint-ignore no-explicit-any
instance?: any;
}>;
export class DependencyManager {
private modules: Modules = new Map();
private resolving: Set<ModuleIdentifier> = new Set();
// Enregistrer un module avec son initialisateur
register<T>(identifier: ModuleIdentifier, provider: Provider<T>): void {
if (this.modules.has(identifier)) {
throw new Error(`Module ${identifier} is already registered.`);
}
this.modules.set(identifier, { provider });
}
// Résoudre un module et ses dépendances
async resolve<T>(identifier: ClassType<T>): Promise<T>;
async resolve<T>(identifier: ModuleIdentifier): Promise<T>;
async resolve(identifier: ModuleIdentifier) {
const module = this.modules.get(identifier);
if (!module) {
throw new Error(`Module ${identifier} is not registered.`);
}
if (module.instance) {
return module.instance;
}
if (this.resolving.has(identifier)) {
throw new Error(`Circular dependency detected for module ${identifier}.`);
}
this.resolving.add(identifier);
try {
module.instance = await module.provider(this);
return module.instance;
} finally {
this.resolving.delete(identifier);
}
}
}