如何解决在 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 放在模块中的 providers 数组中,但消息保持不变。不知道我做错了什么,也许这不是在使用 DI 时实现工厂类的方法? 任何帮助真的很感激!
解决方法
如您所说,SendQueuedEmailsTask
和 TaskFactory
应移入 providers
并从 imports
中移除。
imports
仅用于导入从其他模块导出的服务(related doc),因此 SendQueuedEmailsTask
和 TaskFactory
不属于那里。
为了确保让 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,})
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) {}
// ...
}
它更冗长,但优点是您可以更好地控制注入并避免不同模块之间的服务名称冲突。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。