在nestjs模块中使用相互依赖的多个文件(工厂和实现)



我试图在我的nestjs模块中实现一个服务工厂,但存在依赖性问题。

所有的东西都在一个模块(TaskModule(中,我在里面有三个不同的类,应该可以在模块中使用(TaskService、TaskFactory、SendQueuedEmailsTask(。我猜问题是其中一个文件(TaskFactory(依赖于模块中的其他可注入文件(SendQueuedEmailsTask(?我得到的错误是:

Nest can't resolve dependencies of the TaskFactory (?). Please make sure that the argument SendQueuedEmailsTask at index [0] is available in the TaskFactory context.

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

这是代码:

任务工厂文件

@Injectable()
export class TaskFactory {
constructor(private readonly sendQueuedEmailsTask: SendQueuedEmailsTask) {}
createTask(type: TaskType) {
if(type === 'sendQueuedEmailsTask') return this.sendQueuedEmailsTask;
}
}

SendQueuedEmailsTask实现:

@Injectable()
export class SendQueuedEmailsTask {
readonly actionName = 'sendQueueEmail';
process() {
// task implementation details
}
}

以及它将如何在服务中使用,TaskService:

@Injectable()
export class TaskService {
constructor(
private readonly taskFactory: TaskFactory,
) {}

execute(name: string){
// using TaskFactory             
const Task = this.taskFactory.createTask(name);
Task.process();
}
}

问题出现在我的TaskModule文件中,我认为:

@Module({
imports: [
SendQueuedEmailsTask,
TaskFactory,
],
providers: [TaskService],
controllers: [TaskController],
exports: [TaskService],
})
export class TaskModule {}

已经尝试将SendQueuedEmailsTask和TaskFactory放入模块中的提供程序数组中,但消息保持不变。不知道我做错了什么,也许这不是在使用DI时实现工厂类的方法?非常感谢您的帮助!

如前所述,SendQueuedEmailsTaskTaskFactory应移动到providers中,并从imports中删除。

imports仅用于导入其他模块导出的服务(相关单据(,因此SendQueuedEmailsTaskTaskFactory不属于该模块。

为了确保Nestjs找到您想要注入的服务,您可以在TokenModule:中创建自己的注入令牌

// injection-tokens.ts
export enum InjectionTokens {
SEND_QUEUED_EMAILS_TASK = 'TASK_MODULE/SEND_QUEUED_EMAILS_TASK',
TASK_FACTORY = 'TASK_MODULE/TASK_FACTORY',
TASK_SERVICE = 'TASK_MODULE/TASK_SERVICE',
}

然后创建提供者:

// Create providers.
@Module({
providers: [
{ provide: InjectionTokens.SEND_QUEUED_EMAILS_TASK, useClass: SendQueuedEmailsTask },
{ provide: InjectionTokens.TASK_FACTORY, useClass: TaskFactory },
{ provide: InjectionTokens.TASK_SERVICE, useClass: TaskService },
],
controllers: [TaskController],
exports: [
{ provide: InjectionTokens.TASK_SERVICE, useClass: TaskService },
],
})
export class TaskModule {}

并在您的类中注入服务:

// Inject services.
@Injectable()
export class TaskFactory {
constructor(@Inject(InjectionTokens.SEND_QUEUED_EMAILS_TASK) private readonly sendQueuedEmailsTask: SendQueuedEmailsTask) {}
// ...
}
@Injectable()
export class TaskService {
constructor(@Inject(InjectionTokens.TASK_FACTORY) private readonly taskFactory: TaskFactory) {}

// ...
}

它更详细,但优点是可以更好地控制注入,避免不同模块之间的服务名称冲突。

最新更新