我试图在我的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时实现工厂类的方法?非常感谢您的帮助!
如前所述,SendQueuedEmailsTask
和TaskFactory
应移动到providers
中,并从imports
中删除。
imports
仅用于导入其他模块导出的服务(相关单据(,因此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, 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) {}
// ...
}
它更详细,但优点是可以更好地控制注入,避免不同模块之间的服务名称冲突。