【问题标题】:Is there a way to use static method with dependency injection in NestJS?有没有办法在 NestJS 中使用静态方法和依赖注入?
【发布时间】:2021-04-27 02:03:29
【问题描述】:

一个例子胜于冗长的解释:

// Backery.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Backery } from './Backery.entity';

@Injectable()
export class BackeryService {
  constructor(
    @InjectRepository(Backery)
    private readonly backeryRepository: Repository<Backery>,
  ) {}

  static myStaticMethodToGetPrice() {
    return 1;
  }

  otherMethod() {
    this.backeryRepository.find();
    /* ... */
  }
}
// Backery.resolver.ts
import { Bakery } from './Bakery.entity';
import { BakeryService } from './Bakery.service';

@Resolver(() => Bakery)
export class BakeryResolver {
  constructor() {}

  @ResolveField('price', () => Number)
  async getPrice(): Promise<number> {
    return BakeryService.myStaticMethodToGetPrice(); // No dependency injection here :(
  }
}

如何替换BakeryService.myStaticMethodToGetPrice() 以使用依赖注入,以便我可以轻松地进行测试?

【问题讨论】:

  • 您希望这是一个静态方法有什么特别的原因吗?换句话说,你为什么不能在你的BakeryResolver 中注入BakeryService 并在服务实例上调用price 方法?
  • @eol 该方法不使用this,因此将其设置为静态感觉更自然,因为它不依赖于对象实例。

标签: javascript node.js dependency-injection nestjs


【解决方案1】:

静态方法不能使用依赖注入。这是因为依赖注入(至少对于 Nest)的想法是注入依赖的实例,以便以后可以利用它们。

您拥有的代码是有效的,因为它将像静态方法所说的那样返回值1,但静态方法不能使用任何注入的实例值。您会发现大多数其他 DI 框架都遵循这种逻辑。

【讨论】:

  • 这段代码是有效的,但这是官方推荐的吗?或者最好完全避免使用静态方法以使用 DI 并简化测试?
  • 当涉及到动态模块时,我喜欢避免使用静态的**除了**。
  • 如果您获得对嵌套应用程序对象的引用,则静态方法可以使用 DI。它有一个“resolve”方法,允许您从其 DI 上下文中按类型获取任何对象
【解决方案2】:

有一种非常简单的方法可以创建使用 NestJs DI 中的服务的静态函数。

一个很好的例子是使用领域事件并避免使用技术服务污染实体的构造函数。

在你的 main.ts 中

let app: INestApplication;

async function bootstrap() {
  app = await NestFactory.create(AppModule);

  install();
  ...
  ...
}

bootstrap();

export const getInstance = () => {
  return app;
};

从应用内的任何静态上下文中:

import { getInstance } from '@/main';

static async emmitEvent() {
    let eventEmitter = await getInstance().resolve(EventEmitter2);
    eventEmitter.emit(JSON.stringify(nodeCreateEvent));
}

【讨论】:

  • 你还没有真正让依赖注入与静态方法一起工作,你只是让静态方法引用了可以使用依赖注入的东西。如果您从主应用程序外部运行此静态方法,您将收到运行时错误,因为引导方法可能尚未完成。除此之外,您的main.ts 现在不仅仅用于启动服务器,这开始违反 Nest 试图认可的单一责任原则。
  • 关于 OP 到底想要完成什么并不是很清楚,但我的回答清楚地允许您从静态方法访问应用程序上下文。是的,如果您在应用程序运行上下文之外出于任何原因调用它,它可能会失败。至于单一职责 - 我们更喜欢让我们的实体干净而不是注入,通过构造函数等一堆东西。
猜你喜欢
  • 1970-01-01
  • 2021-03-27
  • 2015-06-06
  • 1970-01-01
  • 2017-07-31
  • 1970-01-01
  • 2013-11-28
  • 1970-01-01
  • 2022-10-19
相关资源
最近更新 更多