# dp-ioc2 **Repository Path**: rajan_admin/dp-ioc2 ## Basic Information - **Project Name**: dp-ioc2 - **Description**: dp-ioc的升级版本 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: dev2 - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-29 - **Last Updated**: 2026-01-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # dp-ioc 简单、强大的基于TypeScript的IOC库。 ## 一、安装 [ Installation ] - npm i dp-ioc ## 二、快速开始 ```typescript import { Inject, Injectable, Provider } from "dp-ioc"; //定义一个可注入类 @Injectable() class Person { name = "rajan" dance() { return this.name + " dance"; } } // 注入到其他类中 class ClassRoom { @Inject(Person) public person:Person; } // 使用,(通过Provider函数进行实例化 ) let classRoom = Provider(ClassRoom); console.log(classRoom.person.name); // rajan console.log(classRoom.person.dance); // rajan dance ``` > 注意,使用了依赖注入的类,在应用时必须通过Provider进行实例化 ## 三、高级用法 ### 3.1 单例 ```typescript import { Single, Injectable } from "dp-ioc"; @Single() @Injectable() class Person { name = "rajan" dance() { return this.name + " dance"; } } ``` ### 3.2 多层注入 ```typescript import { Single, Injectable,Inject,Provider } from "dp-ioc"; @Injectable() class Person { name = "rajan" dance() { return this.name + " dance"; } } @Injectable() class ClassRoom { name = "room 001" @Inject(Person) person:Person } class School { @Inject(ClassRoom) classRoom:ClassRoom; } let school = Provider(School); ``` ### 3.3 构造传参 > 本库支持实例化Injectable可注入对象时,传入实例化的参数 ```typescript import { Single, Injectable,Inject,Provider,Constructor } from "dp-ioc"; @Injectable() class Person { name = "rajan" age = 0; //ioc 容器实例化该类时,setPersonBasicInfo方法将会被执行 @Constructor() setPersonBasicInfo(name:string,age:number){ this.name = name; this.age = age; } dance() { return this.name + " dance"; } } //注入 class ClassRoom { name = "room 001" @Inject(Person,["小明",18]) person:Person } // 实例化 let classRoom = Provider(ClassRoom); console.log(classRoom.person.name,classRoom.person.age); // 小明 18 ``` ### 3.4 支持继承依赖 ```typescript import { Single, Injectable,Inject,Provider,Constructor } from "dp-ioc"; @Injectable() class Human { age = 0; name = ""; } class Student extends Human { dance():string{ return this.name + "dance"; } } class classRoom { @Inject(Student) public Student: Student; } ``` ### 3.5 序列化和反序列 > 在实际项目开发中,某些对象可能需要序列化为字符串以便存储,传输。本库支持将序列化之后的对象还原为依赖对象。 ```typescript import { Single, Injectable,Inject,Provider,Constructor } from "dp-ioc"; @Injectable() class Person { age = 0; name = ""; dance():string{ return this.name + "dance"; } } class ClassRoom { @Inject(Student) public Student: Student; } let classRoom = Provider(ClassRoom); let classRoomStr = JSON.stringify(classRoom); // 序列化为字符串 classRoom = Provider(ClassRoom,JSON.parse(classRoomStr)); // 反序列化为依赖对象 ``` ### 3.6 参数校验 (ParamValidate) > 本库支持方法参数自动校验,支持 class-validator(对象参数)和 joi(非对象参数)两种校验方式。IOC 容器会自动判断参数类型并选择相应的校验方式。 #### 3.6.1 使用 Joi 校验非对象参数 ```typescript import { Injectable, Inject, Provider, ParamValidate } from "dp-ioc"; import Joi from "joi"; @Injectable() class UserService { // 校验字符串参数 getUserById(@ParamValidate(undefined, Joi.string().min(3).required()) id: string) { return `User ${id}`; } // 校验数字参数 calculate( @ParamValidate(undefined, Joi.number().min(0).required()) a: number, @ParamValidate(undefined, Joi.number().min(1).required()) b: number ) { return a / b; } } class App { @Inject(UserService) userService: UserService; } const app = Provider(App); app.userService.getUserById("123"); // ✅ 通过 // app.userService.getUserById("12"); // ❌ 抛出 IOCValidationError ``` #### 3.6.2 使用 class-validator 校验对象参数 ```typescript import { Injectable, Inject, Provider, ParamValidate } from "dp-ioc"; import { IsString, IsNumber, MinLength, Min } from "class-validator"; // 定义校验类 class CreateUserDto { @IsString() @MinLength(3) name!: string; @IsNumber() @Min(18) age!: number; } @Injectable() class UserService { async createUser(@ParamValidate(CreateUserDto) user: CreateUserDto) { return `Created user: ${user.name}, age: ${user.age}`; } } class App { @Inject(UserService) userService: UserService; } const app = Provider(App); // ✅ 使用类实例 const user = new CreateUserDto(); user.name = "John"; user.age = 25; await app.userService.createUser(user); // ✅ 使用普通对象(会自动转换为类实例) await app.userService.createUser({ name: "John", age: 25 }); // ❌ 校验失败会抛出 IOCValidationError // await app.userService.createUser({ name: "Jo", age: 17 }); ``` #### 3.6.3 混合使用 ```typescript import { Injectable, Inject, Provider, ParamValidate } from "dp-ioc"; import Joi from "joi"; import { IsString, MinLength } from "class-validator"; class UserDto { @IsString() @MinLength(3) name!: string; } @Injectable() class UserService { async updateUser( @ParamValidate(undefined, Joi.string().min(3).required()) userId: string, @ParamValidate(UserDto) userData: UserDto ) { return `Updated user ${userId} with name ${userData.name}`; } } ``` #### 3.6.4 错误处理 ```typescript import { IOCValidationError } from "dp-ioc"; try { app.userService.getUserById("12"); } catch (error) { if (error instanceof IOCValidationError) { console.error("参数校验失败:", error.message); console.error("详细错误:", error.errors); } } ``` > **注意**: > - 参数校验在方法调用前自动执行 > - 如果校验失败,会抛出 `IOCValidationError` 异常 > - 参数校验在 Before hook 之前执行 > - 对象参数自动使用 class-validator,非对象参数使用 joi ### 3.7 方法拦截器 (Interceptor) > 拦截器可以完全控制方法的执行流程,包括修改参数、修改返回值、处理错误等。**注意:拦截器不能与 Before 和 After 同时使用。** #### 3.7.1 基本使用 ```typescript import { Injectable, Inject, Provider, Interceptor } from "dp-ioc"; @Injectable() class Service { @Interceptor((args: any[], obj: any, targetFn: Function, done: Function) => { // args: 方法调用的参数列表 // obj: 方法所属的对象实例 // targetFn: 原始的目标方法 // done: 回调函数,用于处理错误或返回结果 (err, result) => void // 可以修改参数 const modifiedArgs = args.map((arg: number) => arg * 2); // 调用原始方法 try { const result = targetFn.apply(obj, modifiedArgs); done(null, result); } catch (error) { done(error, null); } }) calculate(a: number, b: number): number { return a + b; } } class App { @Inject(Service) service: Service; } const app = Provider(App); const result = await app.service.calculate(2, 3); // 参数被修改为 4 和 6,所以结果是 10 console.log(result); // 10 ``` #### 3.7.2 修改返回值 ```typescript @Injectable() class Service { @Interceptor((args: any[], obj: any, targetFn: Function, done: Function) => { const result = targetFn.apply(obj, args); // 修改返回值 done(null, result * 2); }) add(a: number, b: number): number { return a + b; } } ``` #### 3.7.3 处理异步方法 ```typescript @Injectable() class Service { @Interceptor((args: any[], obj: any, targetFn: Function, done: Function) => { Promise.resolve(targetFn.apply(obj, args)) .then(result => done(null, result)) .catch(err => done(err, null)); }) async asyncMethod(value: string): Promise { return new Promise(resolve => { setTimeout(() => resolve(`async_${value}`), 100); }); } } ``` #### 3.7.4 错误处理 ```typescript @Injectable() class Service { @Interceptor((args: any[], obj: any, targetFn: Function, done: Function) => { try { const result = targetFn.apply(obj, args); done(null, result); } catch (error) { // 捕获并处理错误 done(new Error(`Intercepted error: ${error}`), null); } }) throwError(): void { throw new Error("Original error"); } } ``` #### 3.7.5 与参数校验配合使用 ```typescript import { Injectable, Inject, Provider, Interceptor, ParamValidate } from "dp-ioc"; import Joi from "joi"; @Injectable() class Service { @Interceptor((args: any[], obj: any, targetFn: Function, done: Function) => { // 拦截器在参数校验之后执行 const result = targetFn.apply(obj, args); done(null, result); }) test(@ParamValidate(undefined, Joi.string().min(3).required()) value: string): string { return value; } } ``` > **注意**: > - 拦截器不能与 Before 和 After 同时使用,否则会抛出错误 > - 拦截器在参数校验之后执行 > - 拦截器可以完全控制方法的执行流程 > - done 回调函数:第一个参数是错误(如果有),第二个参数是结果 ## 四、支持 如果在使用过程中,遇到问题,请到github仓库反馈,[仓库地址](https://gitee.com/rajan_admin/dp-ioc)。