From 83444c24236942fd0a66ec5f176c00bb47c873a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9opold=20Hubert?= Date: Sat, 15 Jul 2023 12:16:33 +0200 Subject: [PATCH] 'waitForWire' function and better typing --- package-lock.json | 4 ++-- package.json | 2 +- src/Container.ts | 26 ++++++++++++++++------- src/DependencyInjector.ts | 44 ++++++++++++++++++++++++++++----------- src/types.ts | 9 +++++++- 5 files changed, 61 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5422827..e0dd82e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "wire-dependency-injection", - "version": "1.0.7", + "version": "1.0.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "wire-dependency-injection", - "version": "1.0.7", + "version": "1.0.8", "license": "Apache-2.0", "devDependencies": { "@types/node": "^20.4.2", diff --git a/package.json b/package.json index 9fdc52c..9fca960 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wire-dependency-injection", - "version": "1.0.7", + "version": "1.0.8", "description": "An easy to use JavaScript Dependency Injection Library", "main": "dist/index.js", "type": "module", diff --git a/src/Container.ts b/src/Container.ts index abd624b..b21fc25 100644 --- a/src/Container.ts +++ b/src/Container.ts @@ -1,8 +1,14 @@ -import { BeanType, ClassType, ContainerIdType } from './types.js'; +import { + BeanType, + ClassType, + ContainerIdType, + RegisterBeanArgs, +} from './types.js'; import Bean from './Bean.js'; import DependencyAlreadyRegisteredError from './errors/DependencyAlreadyRegisteredError.js'; import DependencyNotFoundError from './errors/DependencyNotFoundError.js'; import { parseId } from './utils.js'; +import { DEFAULT_BEAN_TYPE, DEFAULT_CONTAINER_ID } from './index.js'; /** * Containers holds beans for dependency injection. @@ -12,11 +18,11 @@ import { parseId } from './utils.js'; * const container1 = new Container(CONTAINER1_ID); * const container2 = injector.getContainer(CONTAINER2_ID); * - * container1.registerRawBean('b1', B1); + * container1.registerRawBean(B1, {id: 'b1'}); * // Will throw an error - * container1.registerRawBean('b1', B1bis); + * container1.registerRawBean(B1bis, {id: 'b1'}); * // Will work - * container2.registerRawBean('b1', B1ter); + * container2.registerRawBean(B1ter, {id: 'b1'}); */ export default class Container { /** @@ -96,13 +102,17 @@ export default class Container { /** * Registers a new bean with the specified ID, class, and type in the container. * @param clazz - The class of the bean to register. - * @param id - The ID of the bean to register. Will take the name of the provided class if not provided. - * @param type - The type of the bean. + * @param params - Parameters of the bean. * @returns The registered bean. * @throws DependencyAlreadyRegisteredError if a bean with the same ID is already registered. */ - public registerRawBean(clazz: ClassType, id?: string, type?: BeanType) { - const bean = new Bean(clazz, id, type); + public registerRawBean(clazz: ClassType, params: RegisterBeanArgs = {}) { + const defParams: RegisterBeanArgs = { + type: DEFAULT_BEAN_TYPE, + containerId: DEFAULT_CONTAINER_ID, + ...params, + }; + const bean = new Bean(clazz, defParams.id, defParams.type); return this.registerCookedBean(bean); } } diff --git a/src/DependencyInjector.ts b/src/DependencyInjector.ts index 789bc9c..f69d528 100644 --- a/src/DependencyInjector.ts +++ b/src/DependencyInjector.ts @@ -3,6 +3,7 @@ import { BeanType, ClassType, ContainerIdType, + RegisterBeanArgs, } from './types.js'; import { DEFAULT_BEAN_TYPE, @@ -25,7 +26,7 @@ import { parseId } from './utils.js'; * class MyService { ... } * injector.registerBean(MyService); // ID will be the name of the class * // You can also give a different ID to your bean - * injector.registerBean(MyService, 'MySuperService'); + * injector.registerBean(MyService, {id: 'MySuperService'}); * * // To connect to a bean when this one is registered use the `wire` function. * const myService = injector.wire(MyService); @@ -206,23 +207,21 @@ export default class DependencyInjector { * } * injector.registerBean(MyService); * @param clazz - The class of the bean to register. - * @param id - The ID of the bean to register. Will take the name of the provided class if not provided. - * @param type - The type of the bean. - * @param containerId - The ID of the container to register the bean in. + * @param params - Parameters of the bean. * @returns The registered bean. * @throws ContainerNotFoundError if the specified container does not exist. */ - public registerBean( - clazz: ClassType, - id?: string, - type: BeanType = DEFAULT_BEAN_TYPE, - containerId: string = DEFAULT_CONTAINER_ID - ) { - const container = this.getContainer(containerId); + public registerBean(clazz: ClassType, params: RegisterBeanArgs = {}) { + const defParams: RegisterBeanArgs = { + type: DEFAULT_BEAN_TYPE, + containerId: DEFAULT_CONTAINER_ID, + ...params, + }; + const container = this.getContainer(defParams.containerId); if (!container) { throw new ContainerNotFoundError(); } - const retBean = container.registerRawBean(clazz, id, type); + const retBean = container.registerRawBean(clazz, defParams); this.executeAutoWireQueue(); return retBean; } @@ -279,4 +278,25 @@ export default class DependencyInjector { } return bean.getInstance() as InstanceType; } + + /** + * Returns a Promise that resolves with the wired instance. + * @param id - The ID or class of the bean to wait for AutoWire. + * @param containerId - The ID of the container to retrieve the bean from. Defaults to DEFAULT_CONTAINER_ID. + * @returns A Promise that resolves with the wired instance of the bean. + */ + public waitForWire( + id: string | T, + containerId: string = DEFAULT_CONTAINER_ID + ) { + return new Promise((resolve) => { + this.autoWire( + id, + (b) => { + resolve(b as InstanceType); + }, + containerId + ); + }); + } } diff --git a/src/types.ts b/src/types.ts index af44411..95e7633 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,7 +1,14 @@ -export type ClassType = new (...args: unknown[]) => unknown; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type ClassType = new (...args: any) => any; export type BeanType = 'bean' | (string & NonNullable); export type ContainerIdType = 'default' | (string & NonNullable); //we trick typescript and avoid errors by setting val type to undefined export type AutowiredDescriptor = (val: undefined) => void; + +export type RegisterBeanArgs = { + id?: string; + type?: BeanType; + containerId?: ContainerIdType; +};