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

未初始化调用类函数:NestJS中ExampleService实例化报错问题

问题根源

你在TelegrafModule里能直接用ExampleService不用传参数,是因为NestJS的依赖注入(DI)容器在背后帮你做了所有事:它会自动解析ExampleService的所有依赖、创建实例,然后注入到你的类里。

但layouts.telegraf.ts里的是普通函数,不在Nest的DI容器管理范围内,手动new ExampleService()就必须自己传入它要求的所有依赖参数,所以才会报错。

解决方案

1. 把函数封装成Nest服务(最推荐)

把你的test函数放到一个被Nest管理的Service里,这样就能继续用依赖注入,不用手动处理实例化:

第一步:创建LayoutsService

新建layouts.service.ts:

import { Injectable } from '@nestjs/common';
import { ExampleService } from 'path/to/ExampleService';

@Injectable()
export class LayoutsService {
  constructor(private readonly exampleService: ExampleService) {}

  async test() {
    this.exampleService.ping(true);
  }
}

第二步:在模块里注册这个服务

修改telegram.module.ts,把LayoutsService加入提供者列表:

import {Module} from '@nestjs/common';
import {TelegrafModule} from 'nestjs-telegraf';
import {TelegramService} from './telegram.service';
import {ExampleModule} from 'path/to/ExampleModule';
import { LayoutsService } from './layouts.service'; // 导入新服务

@Module({
    imports: [
        TelegrafModule.forRootAsync({
            useFactory: () => ({
                token: settings.bots.token,
                middlewares: [sessionMiddleware],
                launchOptions: {
                    webhook: {
                        domain: settings.bots.domain,
                        hookPath: '/telegram',
                    }
                }
            }),
        }),
        ExampleModule.register()
    ],
    providers: [TelegramService, LayoutsService], // 添加到提供者
    exports: [LayoutsService] // 如果其他模块要用到,就加这句导出
})
export class TelegramModule{}

之后你在任何Nest管理的类里,都可以通过构造函数注入LayoutsService来调用test方法。

2. 从Nest全局容器获取实例(适合特殊场景)

如果必须在普通函数里用,可以在应用启动时保存Nest的容器引用,然后从容器里拿ExampleService实例:

第一步:保存容器引用

修改main.ts:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

// 全局变量保存容器
export let nestContainer;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  nestContainer = app.getContainer();
  await app.listen(3000);
}
bootstrap();

第二步:在普通函数里使用

修改layouts.telegraf.ts:

import { ExampleService } from 'path/to/ExampleService';
import { nestContainer } from './main';

export async function test() {
  // 从容器获取已创建的ExampleService实例
  const exampleService = nestContainer.get(ExampleService);
  exampleService.ping(true);
}

⚠️ 注意:这种方式会破坏依赖注入的解耦性,尽量少用,只适合实在没法封装成Service的场景。

3. 手动传入依赖(不推荐)

如果ExampleService的依赖很简单,你也可以手动创建它的依赖实例,再传给ExampleService:

import { ExampleService } from 'path/to/ExampleService';
// 导入ExampleService需要的依赖
import { SomeDependency } from 'path/to/SomeDependency';

// 手动创建依赖实例
const someDependency = new SomeDependency();
// 传入依赖创建ExampleService实例
const exampleService = new ExampleService(someDependency);

export async function test() {
  exampleService.ping(true);
}

这种方式耦合度极高,后续ExampleService的依赖变化时,你得手动修改所有实例化的地方,不推荐在Nest项目里用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 06:36:32