allow the use of a class as dependency identifier
This commit is contained in:
@@ -1,44 +1,53 @@
|
||||
type Provider<T> = (manager: DependencyManager) => Promise<T> | T;
|
||||
|
||||
type Modules = Map<string, {
|
||||
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<string> = new Set();
|
||||
private resolving: Set<ModuleIdentifier> = new Set();
|
||||
|
||||
// Enregistrer un module avec son initialisateur
|
||||
register<T>(name: string, provider: Provider<T>): void {
|
||||
if (this.modules.has(name)) {
|
||||
throw new Error(`Module ${name} is already registered.`);
|
||||
register<T>(identifier: ModuleIdentifier, provider: Provider<T>): void {
|
||||
if (this.modules.has(identifier)) {
|
||||
throw new Error(`Module ${identifier} is already registered.`);
|
||||
}
|
||||
this.modules.set(name, { provider });
|
||||
this.modules.set(identifier, { provider });
|
||||
}
|
||||
|
||||
// Résoudre un module et ses dépendances
|
||||
async resolve<T>(name: string): Promise<T> {
|
||||
const module = this.modules.get(name);
|
||||
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 ${name} is not registered.`);
|
||||
throw new Error(`Module ${identifier} is not registered.`);
|
||||
}
|
||||
|
||||
if (module.instance) {
|
||||
return module.instance;
|
||||
}
|
||||
|
||||
if (this.resolving.has(name)) {
|
||||
throw new Error(`Circular dependency detected for module ${name}.`);
|
||||
if (this.resolving.has(identifier)) {
|
||||
throw new Error(`Circular dependency detected for module ${identifier}.`);
|
||||
}
|
||||
|
||||
this.resolving.add(name);
|
||||
this.resolving.add(identifier);
|
||||
|
||||
try {
|
||||
module.instance = await module.provider(this);
|
||||
return module.instance;
|
||||
} finally {
|
||||
this.resolving.delete(name);
|
||||
this.resolving.delete(identifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user