You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS中如何将Service注入普通TypeScript类?

在NestJS普通TypeScript类中注入Service的解决方案

你的问题核心在于:NestJS的依赖注入(DI)系统仅管理被@Injectable()装饰的类或模块内的提供者,而你定义的Stream是普通TypeScript类,Nest不会自动解析它的@Inject装饰器,导致analysisService始终为undefined。

下面是几种实用的解决方法:


方案一:创建Stream实例时手动传入AnalysisService(推荐)

这是最直接简单的方式,在需要生成Stream实例的地方(通常是Nest管理的服务中),先注入AnalysisService,再通过构造函数参数传递给Stream。

修改Stream类

import { AnalysisService } from './analysis.service';
import * as ccxt from 'ccxt';

export class Stream {
  private exchange: ccxt.Exchange;
  private market: ccxt.Market;
  private timeframe: string;
  private ohlcv_cache: ccxt.OHLCV[];
  private createdAt: Date;
  private stream;

  constructor(
    private readonly analysisService: AnalysisService,
    exchange: ccxt.Exchange,
    market: ccxt.Market,
    timeframe: string
  ) {
    this.exchange = exchange;
    this.market = market;
    this.timeframe = timeframe;
    this.createdAt = new Date();
    this.initialize();
    console.log(this.analysisService); // 现在能正常获取实例
  }

  // 示例:调用AnalysisService的方法
  async calculateRSI(period: number = 14) {
    if (!this.ohlcv_cache) return null;
    return await this.analysisService.RSI(this.ohlcv_cache, period);
  }

  private initialize() {
    // 你的初始化逻辑
  }
}

在Nest服务中创建Stream实例

import { Injectable } from '@nestjs/common';
import { AnalysisService } from './analysis.service';
import { Stream } from './stream';
import * as ccxt from 'ccxt';

@Injectable()
export class StreamManagerService {
  constructor(private readonly analysisService: AnalysisService) {}

  createStream(exchange: ccxt.Exchange, market: ccxt.Market, timeframe: string) {
    return new Stream(this.analysisService, exchange, market, timeframe);
  }
}

方案二:使用ModuleRef动态获取Service(适合非Nest管理代码创建Stream的场景)

如果你的Stream实例需要在非Nest控制的代码中创建,可以通过ModuleRef手动获取AnalysisService实例。

全局保存ModuleRef

import { Module, OnModuleInit } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';
import { AnalysisModule } from './analysis.module';

@Module({
  imports: [AnalysisModule],
})
export class AppModule implements OnModuleInit {
  static moduleRef: ModuleRef;

  constructor(private readonly moduleRef: ModuleRef) {}

  onModuleInit() {
    AppModule.moduleRef = this.moduleRef;
  }
}

外部代码中创建Stream

import { AppModule } from './app.module';
import { Stream } from './stream';
import * as ccxt from 'ccxt';

// 示例:在非Nest服务的代码中创建Stream
const createStream = async () => {
  const exchange = new ccxt.binance();
  const market = await exchange.loadMarket('BTC/USDT');
  // 从ModuleRef获取AnalysisService
  const analysisService = AppModule.moduleRef.get(AnalysisService);
  return new Stream(analysisService, exchange, market, '1h');
};

方案三:将Stream转为Nest可注入类,用工厂模式生成动态实例

如果希望Stream也被Nest的DI系统管理,同时支持动态传入exchange、market等参数,可以使用自定义工厂提供者。

修改Stream类为可注入

import { Injectable, Inject } from '@nestjs/common';
import { AnalysisService } from './analysis.service';
import * as ccxt from 'ccxt';

@Injectable()
export class Stream {
  private exchange: ccxt.Exchange;
  private market: ccxt.Market;
  private timeframe: string;
  private ohlcv_cache: ccxt.OHLCV[];
  private createdAt: Date;
  private stream;

  constructor(
    private readonly analysisService: AnalysisService,
    @Inject('STREAM_OPTIONS') private readonly options: {
      exchange: ccxt.Exchange;
      market: ccxt.Market;
      timeframe: string;
    }
  ) {
    this.exchange = options.exchange;
    this.market = options.market;
    this.timeframe = options.timeframe;
    this.createdAt = new Date();
    this.initialize();
  }

  private initialize() {
    // 你的初始化逻辑
  }
}

定义工厂提供者并创建实例

import { Injectable } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';
import { Stream } from './stream';
import * as ccxt from 'ccxt';

@Injectable()
export class StreamManagerService {
  constructor(private readonly moduleRef: ModuleRef) {}

  async createStream(exchange: ccxt.Exchange, market: ccxt.Market, timeframe: string) {
    // 动态注册Stream提供者
    const streamProvider = {
      provide: Stream,
      useFactory: (analysisService: AnalysisService) => {
        return new Stream(analysisService, { exchange, market, timeframe });
      },
      inject: [AnalysisService],
    };
    this.moduleRef.register(streamProvider);
    return this.moduleRef.get(Stream);
  }
}

内容的提问来源于stack exchange,提问作者BitQueen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 10:55:21