- 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>
55 lines
1.9 KiB
TypeScript
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();
|
|
};
|
|
};
|
|
}
|