Files
TSinjex/src/decorators/Inject.ts
Max P. 46c9a8b990 refactor(di): modularize and improve dependency injection for deno
- Consolidate import paths into scoped modules for better structure.
- Refactor decorators (`Inject`, `Register`) for improved type safety.
- Add `clear` method to the DI container for easier test cleanup.
- Introduce lazy initialization for registered instances.
- Add comprehensive unit tests for decorators and DI container.
- Standardize error handling and naming conventions for exceptions.

Signed-off-by: Max P. <Mail@MPassarello.de>
2025-05-02 19:55:16 +02:00

55 lines
1.9 KiB
TypeScript

import { TSinjex } from "../classes/mod.ts";
import { InitializationError } from "../interfaces/mod.ts";
import { Identifier, InitDelegate } from "../types/mod.ts";
export function Inject<InstanzType, DependencyType, FieldType extends object>(
identifier: Identifier,
init?: InitDelegate<DependencyType, FieldType>,
isNecessary = true,
): (
target: undefined,
context: ClassFieldDecoratorContext<InstanzType, FieldType>,
) => (initialValue: FieldType) => FieldType {
return function (
_target: undefined,
context: ClassFieldDecoratorContext<InstanzType, FieldType>,
): (initialValue: FieldType) => FieldType {
if (context.kind !== "field") {
throw new Error("Inject decorator can only be used on fields.");
}
const initializer = () => {
let instance: DependencyType | FieldType | undefined;
const dependency: DependencyType | undefined = TSinjex.getInstance()
.resolve<DependencyType>(identifier, isNecessary);
if (init == null || dependency == null) {
instance = dependency;
} else {
try {
instance = init(dependency);
} catch (error) {
if (isNecessary) {
throw new InitializationError(
identifier,
error instanceof Error ? error : new Error(String(error)),
);
} else {
console.warn(
`Error initializing not necessary dependency ${identifier.toString()}: ${error}`,
);
instance = undefined;
}
}
}
return instance as FieldType;
};
return function (_initialValue: FieldType): FieldType {
return initializer();
};
};
}