为什么在 Nestjs 中导入类的不同方式会影响依赖注入?

Why different ways of importing classes in Nestjs affect dependency injection?

提问人:zhangzuiwokankanluntai 提问时间:10/16/2023 最后编辑:Heretic Monkeyzhangzuiwokankanluntai 更新时间:10/16/2023 访问量:43

问:

我正在用打字稿开发 NestJS 项目。 我正在尝试将一个类注入构造函数,如下所示:

@Injectable()
export class AuthService {
  constructor(
    ...Some omitted content,
    private loginFactory: LoginFactory,
  ) {}
}

LoginFactory 是一个工厂类,如下所示:

@Injectable()
export class LoginFactory {
  constructor(
    private readonly phoneLoginService: PhoneLoginService,
    private readonly verificationCodeLoginService: VerificationCodeLoginService,
  ) {}
}

PhoneLoginService 类和 VerificationCodeLoginService 类都继承了一个名为 AbstractLoginService 的抽象类,如下所示:

@Injectable()
export class PhoneLoginService extends AbstractLoginService {
  constructor(protected readonly userService: UserService) {
    super(userService);
  }
}
@Injectable()
export class VerificationCodeLoginService extends AbstractLoginService {
  constructor(protected readonly userService: UserService) {
    super(userService);
  }
}

AbstractLoginService 抽象类如下所示:

export abstract class AbstractLoginService<T extends LoginDto = LoginDto> {
  constructor(protected readonly userService: UserService) {}
  ...Some omitted content
}

我的 AuthModule 内容如下:

@Module({
  ...Some omitted content
  providers: [
    AuthService,
    PhoneLoginService,
    VerificationCodeLoginService,
    LoginFactory,
  ],
})
export class AuthModule {}

我的代码运行良好,直到我最近清理了文件结构。具体来说,我在 AuthService 中导入 LoginFactory 的方式是这样的: 由于上述服务类都在 services 目录中,因此我添加了一个名为 index.ts 的新文件,作为统一出口。其内容如下:import { LoginFactory } from './login-factory.service';

export * from './abstract-login.service';
export * from './auth.service';
export * from './login-factory.service';
export * from './phone-login.service';
export * from './verificationCode-login.service';

同时,我在 AuthService 类中更改了 LoginFactory 类的导入方法,如下所示:

import { LoginFactory } from './';

但是,当我再次启动该项目时,我报告了以下错误:

Error: Nest can't resolve dependencies of the LoginFactory (?, +). Please make sure that the argument dependency at index [0] is available in the AuthModule context.

Potential solutions:
- Is AuthModule a valid NestJS module?
- If dependency is a provider, is it part of the current AuthModule?
- If dependency is exported from a separate @Module, is that module imported within AuthModule?
  @Module({
    imports: [ /* the Module containing dependency */ ]
  })

注入 LoginFactory 类似乎有问题。但是当我更改了 LoginFactory 在 AuthService 类中的导入方式时,一切都恢复了正常。具体来说,我将导入方法更改了回来,如下所示: 我猜这可能是导入顺序的问题。但这只是猜测。 我将不胜感激您的帮助。import { LoginFactory } from './login-factory.service';

我试着一点一点地改变文件的导入方式,最后确定是LoginFactory的导入方式影响了项目的正常运行

节点 .js 打字稿 nestjs 抽象类

评论


答:

1赞 Jay McDoniel 10/16/2023 #1

当您使用 barrel import(或类似的东西)时,您不仅从该相关文件导入必要的文件,还从该文件导入所有导出,并且每个文件也导入它需要的所有内容。在本例中,您将在文件本身上创建循环导入语句。 import from 意味着它导入 、 和 others。导入的事实已经是一个危险信号,但是如果你看一下它从中导入,那么它也会导入,现在你有一个由两部分组成的循环链,这可以持续到尽可能多的文件。././authindex.tsauth.service./auth.serviceabstract-ogin.servicelogin-factory.serviceauth.serviceauth.servicelogin-factory.service./auth.service

我对桶文件的一般规则是,从功能外部导入是可以的,但从功能内部,直接从文件导入。这也有助于区分该功能的公共 API 和私有 API。

评论

0赞 zhangzuiwokankanluntai 10/16/2023
感谢您的帮助,这解决了我的一个大难题。非常感谢。