您可以在 Angular / NestJS 模块提供程序中使用 `useFactory` 属性并返回一个类而不是实例吗?
Posted
技术标签:
【中文标题】您可以在 Angular / NestJS 模块提供程序中使用 `useFactory` 属性并返回一个类而不是实例吗?【英文标题】:Can you use the `useFactory` property in the Angular / NestJS Module Provider and return a Class instead of an instance? 【发布时间】:2021-04-30 04:20:17 【问题描述】:我正在使用 NestJS 构建 API。我有一个到第 3 方 API 的网关服务,它将 HTTP 调用与数据处理逻辑分离。由于我不想在开发期间向 API 发出请求,因此我使用了一个工厂函数,该函数根据环境返回一个 Gateway 类——TinkMockGateway 或 TinkGateway。
在工厂函数中,我返回类而不是实例,它可以工作。这是令人惊讶的,因为我的实现不同于 Angular / NestJS 文档。在两个文档 [1, 2] 中,他们都说您必须返回要注入的类的实例——如果我们遵循工厂模式,这很有意义。
但是,当我使用下面的工厂函数(NestJS)时,依赖项会根据环境正确注入(网关)。
// other module providers...
provide: TinkGateway,
useFactory: () => environment.mockTinkGateway ? TinkMockGateway : TinkGateway,
框架是为我创建实例还是发生了什么?
【问题讨论】:
【参考方案1】:不一样。
通过对 DI 使用 useFactory
方法,您必须返回一个实例。这就是工厂模式所说的,似乎这也是 Angular / NestJS 开发人员所期望的。
如果您使用 useFactory 然后返回一个类(而不是实例),您将在依赖于网关的类中获得该类。但是,您想要的是一个(可能共享的)实例。毕竟,这就是依赖注入的目的。看看下面两个console.dir
的例子:
-
使用类(与您的问题中的代码相同):
// bank.repository.ts
//
// Adding a console.dir to see what's the output
@Injectable()
export class BankRepository implements IBankRepository
constructor(private tinkGateway: TinkGateway)
console.dir(tinkGateway);
// Output
>>> [Function: TinkGateway]
-
使用实例:
// Adding the following provider in the module
// (substituting your previous provider).
// ...other providers
provide: TinkGateway,
useFactory: () =>
environment.mockTinkGateway
? new TinkMockGateway()
: new TinkGateway(),
inject: [HttpService, ConfigService],
,
// more providers...
// Output
>>> TinkGateway
【讨论】:
以上是关于您可以在 Angular / NestJS 模块提供程序中使用 `useFactory` 属性并返回一个类而不是实例吗?的主要内容,如果未能解决你的问题,请参考以下文章
带有nestjs的Angular-universal:错误:找不到模块'./drivers/node-mongodb-native/connection'