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
相关产品推荐
相关产品推荐

