Nestjs教程使用TypeDI进行依赖注入与生命周期管理

在Nestjs项目中使用TypeDI进行依赖注入时遇到几个问题:

  1. TypeDI与Nestjs内置的DI容器如何兼容?是否需要完全替换Nest的默认注入方式?
  2. 生命周期管理方面,TypeDI的@Singleton@Transient与Nest的@Injectable生命周期有何区别?两者能否混用?
  3. 实际案例中遇到循环依赖时,TypeDI的解决方案和Nestjs官方推荐的forwardRef哪种更推荐?
  4. 项目迁移时,现有Nestjs服务层代码如何渐进式改造为TypeDI风格?是否有自动化工具辅助?
  5. TypeDI在Nestjs中的典型错误场景有哪些?(例如单元测试时容器未重置等)

3 回复

在NestJS中,使用TypeDI进行依赖注入(DI)和生命周期管理非常灵活。首先安装TypeDI及相关包:

npm install [@nestjs](/user/nestjs)/common inversify reflect-metadata --save
  1. 注册类型:为需要注入的类创建一个TypeDI的“类型”。

    import { injectable } from 'inversify';
    
    [@injectable](/user/injectable)()
    export class MyService {
      doSomething() {
        console.log('Doing something!');
      }
    }
    
  2. 绑定服务:在模块的onModuleInit钩子中使用Container来绑定服务。

    import { Module, OnModuleInit } from '[@nestjs](/user/nestjs)/common';
    import { Container } from 'inversify';
    import { MyService } from './my.service';
    
    [@Module](/user/Module)({})
    export class AppModule implements OnModuleInit {
      private readonly container = new Container();
    
      onModuleInit() {
        this.container.bind<MyService>('MyService').to(MyService);
      }
    
      getMyService(): MyService {
        return this.container.get<MyService>('MyService');
      }
    }
    
  3. 生命周期管理:TypeDI支持多种生命周期钩子,如@inject@postConstruct,用于初始化逻辑。

  4. 注入服务:通过构造函数获取服务实例。

    export class SomeOtherClass {
      constructor(private myService: MyService) {}
    
      run() {
        this.myService.doSomething();
      }
    }
    

结合NestJS框架特性,这种模式可以实现复杂应用的依赖管理和解耦。


在NestJS中使用TypeDI进行依赖注入(DI)和生命周期管理,首先需要安装TypeDI及相关依赖:

npm install [@nestjs](/user/nestjs)/common [@nestjs](/user/nestjs)/core type.di reflect-metadata
  1. 基础配置
    main.ts中添加必要的反射元数据支持:

    import 'reflect-metadata';
    
  2. 定义服务
    使用@Service()装饰器定义一个服务,并通过[@Injectable](/user/Injectable)()指定其生命周期:

    import { Injectable } from 'type.di';
    
    [@Injectable](/user/Injectable)({ transient: true }) // 或者 singleton、request
    export class MyService {
        doSomething() {
            console.log('Doing something!');
        }
    }
    
  3. 注册到模块
    在模块文件中注册服务:

    import { Module } from '[@nestjs](/user/nestjs)/common';
    import { MyService } from './my.service';
    
    [@Module](/user/Module)({
        providers: [MyService],
    })
    export class AppModule {}
    
  4. 注入服务
    在控制器或其他服务中注入:

    import { Controller, Get } from '[@nestjs](/user/nestjs)/common';
    import { MyService } from './my.service';
    
    [@Controller](/user/Controller)()
    export class MyController {
        constructor(private readonly myService: MyService) {}
    
        @Get()
        getHello(): string {
            this.myService.doSomething();
            return 'Hello World!';
        }
    }
    

通过上述步骤,即可实现依赖注入及生命周期管理。生命周期模式包括transient(每次请求新实例)、singleton(单例)和request(每次请求一个新实例)。

NestJS中使用TypeDI进行依赖注入与生命周期管理

TypeDI是一个功能强大的依赖注入容器,可以与NestJS结合使用来增强其原有的依赖注入系统。以下是基本使用方法:

安装TypeDI

npm install typedi reflect-metadata

基本配置

main.ts中导入reflect-metadata:

import 'reflect-metadata';

服务类使用TypeDI

import { Service } from 'typedi';

@Service()
export class UserService {
  getUsers() {
    return ['John', 'Jane'];
  }
}

在控制器中使用

import { Controller, Get } from '@nestjs/common';
import { Container } from 'typedi';
import { UserService } from './user.service';

@Controller('users')
export class UserController {
  private userService = Container.get(UserService);

  @Get()
  getUsers() {
    return this.userService.getUsers();
  }
}

生命周期管理

TypeDI支持以下生命周期:

  1. Transient - 每次请求都创建新实例
  2. Singleton - 单例模式(默认)
  3. Request - 每个请求周期内是单例
import { Service, Scope } from 'typedi';

@Service({ scope: Scope.REQUEST })  // 请求生命周期
export class RequestScopedService {
  // ...
}

与NestJS原生DI结合

你可以通过提供者方式集成:

import { Provider } from '@nestjs/common';
import { Container } from 'typedi';
import { UserService } from './user.service';

const UserServiceProvider: Provider = {
  provide: UserService,
  useValue: Container.get(UserService),
};

@Module({
  providers: [UserServiceProvider],
})
export class AppModule {}

TypeDI提供了比NestJS原生DI更灵活的依赖注入方案,特别适合复杂应用场景。

回到顶部