NestJS Nest 无法解析 RolesService 的依赖项(+、+、?)
NestJS Nest can't resolve dependencies of the RolesService (+, +, ?)
您好,我正在使用 NestJS 框架(使用 MongoDB)进行编程,现在已经构建了一些模块。当我尝试从另一个模块导入模型时 returns 这个错误:
Nest can't resolve dependencies of the RolesService (+, +, ?).
现在,我实现了这样的代码:
app.module.ts
import { GroupsModule } from './groups/groups.module';
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { UsersModule } from 'users/users.module';
import { RolesModule } from 'roles/roles.module';
@Module({
imports: [
MongooseModule.forRoot('mongodb://localhost:27017/example'),
UsersModule,
GroupsModule,
RolesModule,
],
providers: [],
})
export class AppModule {}
users.module.ts
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { RolesService } from 'roles/roles.service';
import { UserSchema } from './schemas/user.schema';
import { RoleSchema } from 'roles/schemas/role.schema';
@Module({
imports: [
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]),
MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }]),
],
controllers: [UsersController],
providers: [UsersService, RolesService],
exports: [UsersService],
})
export class UsersModule {}
users.service.ts
import { Model } from 'mongoose';
import { ObjectID } from 'mongodb';
import { InjectModel } from '@nestjs/mongoose';
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { User } from './interfaces/user.interface';
@Injectable()
export class UsersService {
constructor(@InjectModel('User') private readonly userModel: Model<User>) {}
}
groups.module.ts
import { MongooseModule } from '@nestjs/mongoose';
import { GroupsController } from './groups.controller';
import { RolesService } from '../roles/roles.service';
import { GroupsService } from './groups.service';
import { GroupSchema } from './schemas/group.schema';
import { UserSchema } from '../users/schemas/user.schema';
import { RoleSchema } from '../roles/schemas/role.schema';
@Module({
imports: [
MongooseModule.forFeature([{ name: 'Group', schema: GroupSchema }]),
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]),
MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }]),
],
controllers: [GroupsController],
providers: [GroupsService, RolesService],
exports: [GroupsService],
})
groups.service.ts
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { ObjectID } from 'mongodb';
import { Model } from 'mongoose';
import { Group } from './interfaces/group.interface';
import { User } from '../users/interfaces/user.interface';
import { CreateGroupDto } from './dto/create-group.dto';
import { RolesDto } from 'roles/dto/roles.dto';
import { Role } from '../roles/interfaces/role.interface';
@Injectable()
export class GroupsService {
constructor(@InjectModel('Group') private readonly groupModel: Model<Group>,
@InjectModel('Role') private readonly roleModel: Model<Role>) {} }
roles.module.ts
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { RolesController } from './roles.controller';
import { RolesService } from './roles.service';
import { RoleSchema } from './schemas/role.schema';
import { UserSchema } from '../users/schemas/user.schema';
import { GroupSchema } from '../groups/schemas/group.schema';
@Module({
imports: [
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]),
MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }]),
MongooseModule.forFeature([{ name: 'Group', schema: GroupSchema }]),
],
controllers: [RolesController],
providers: [RolesService],
exports: [RolesService],
})
export class RolesModule {}
roles.service.ts
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { ObjectID } from 'mongodb';
import { Model } from 'mongoose';
import { Role } from './interfaces/role.interface';
import { User } from '../users/interfaces/user.interface';
import { Group } from '../groups/interfaces/group.interface';
import { CreateRoleDto } from './dto/create-role.dto';
import { RolesDto } from './dto/roles.dto';
@Injectable()
export class RolesService {
constructor( @InjectModel('Role') private readonly roleModel: Model<Role>,
@InjectModel('User') private readonly userModel: Model<User>,
@InjectModel('Group') private readonly groupModel: Model<Group> ) {} }
虽然用户和角色中的 DI 工作正常,但当我尝试在角色服务中导入组模型时出现错误。如果您发现任何错误,请告诉我,我遵循了来自组用户的相同模式,但遗憾的是看不到错误所在。
提前致谢。
更新:好的,我认为我的错误是当我尝试在模块外使用模块服务功能时。我的意思是我修改了(为了简化)我会这样修改代码:
users.module.ts
@Module({
imports: [
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]),
RolesModule,
],
controllers: [UsersController],
providers: [UsersService, RolesService],
exports: [UsersService],
})
export class UsersModule {}
users.controller.ts
export class UsersController {
constructor(private readonly usersService: UsersService,
private readonly rolesService: RolesService){}
async addRoles(@Param('id') id: string, @Body() userRolesDto: UserRolesDto): Promise<User> {
try {
return this.rolesService.setRoles(id, userRolesDto);
} catch (e){
const message = e.message.message;
if ( e.message.error === 'NOT_FOUND'){
throw new NotFoundException(message);
} else if ( e.message.error === 'ID_NOT_VALID'){
throw new BadRequestException(message);
}
}
}
}
roles.module.ts
@Module({
imports: [
MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }]),
],
controllers: [RolesController],
providers: [RolesService],
exports: [RolesService],
})
export class RolesModule {}
roles.service.ts
@Injectable()
export class RolesService {
userModel: any;
constructor( @InjectModel('Role') private readonly roleModel: Model<Role> ) {}
// SET USER ROLES
async setRoles(id: string, rolesDto: RolesDto): Promise<User> {
if ( !ObjectID.isValid(id) ){
throw new HttpException({error: 'ID_NOT_VALID', message: `ID ${id} is not valid`, status: HttpStatus.BAD_REQUEST}, 400);
}
try {
const date = moment().valueOf();
const resp = await this.userModel.updateOne({
_id: id,
}, {
$set: {
updated_at: date,
roles: rolesDto.roles,
},
});
if ( resp.nModified === 0 ){
throw new HttpException({ error: 'NOT_FOUND', message: `ID ${id} not found or entity not modified`, status: HttpStatus.NOT_FOUND}, 404);
} else {
let user = await this.userModel.findOne({ _id: id });
user = _.pick(user, ['_id', 'email', 'roles', 'created_at', 'updated_at']);
return user;
}
} catch (e) {
if ( e.message.error === 'NOT_FOUND' ){
throw new HttpException({ error: 'NOT_FOUND', message: `ID ${id} not found or entity not modified`, status: HttpStatus.NOT_FOUND}, 404);
} else {
throw new HttpException({error: 'ID_NOT_VALID', message: `ID ${id} is not valid`, status: HttpStatus.BAD_REQUEST}, 400);
}
}
}
就是这样,正如您所见,当我尝试使用 users.controller 中的 roles.service setRole 方法时,它 returns 给我一个错误:
Nest 无法解析 RolesService 的依赖项 (?)。请确保索引 [0] 处的参数在当前上下文中可用。
我不明白问题出在哪里,因为我已经在 roles.module 中注入角色模型,但它不理解。事实上,如果我不创建从 users.module 到此依赖项的调用,一切都会正常进行。
有什么建议吗?
(Whosebug的建议我已经红了,以后不会了)
我认为问题在于您多次导入同一个模型,例如:
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]
并且还多次提供相同的服务:
providers: [RolesService]
我不会注入模型本身,而是注入封装模型的相应服务。然后你 export
在其模块中的服务并在需要的地方导入模块。所以 RolesService
会注入 UsersSerivce
而不是 UserModel
.
使用您当前的设置,您会 运行 进入循环依赖。这可以用 fowardRef(() => UserService)
来处理,但应该尽可能避免,参见 circular dependency docs。但是,这是否可以避免取决于您的业务逻辑。
如果你没有循环依赖,那么例如导出你的 RolesService
@Module({
imports: [MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }])]
controllers: [RolesController],
providers: [RolesService],
exports: [RolesService],
})
export class RolesModule {}
并在任何你想使用 RolesService
的地方导入 RolesModule
,例如:
@Module({
imports: [
RolesModule,
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }])
],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService],
})
您好,我正在使用 NestJS 框架(使用 MongoDB)进行编程,现在已经构建了一些模块。当我尝试从另一个模块导入模型时 returns 这个错误:
Nest can't resolve dependencies of the RolesService (+, +, ?).
现在,我实现了这样的代码:
app.module.ts
import { GroupsModule } from './groups/groups.module';
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { UsersModule } from 'users/users.module';
import { RolesModule } from 'roles/roles.module';
@Module({
imports: [
MongooseModule.forRoot('mongodb://localhost:27017/example'),
UsersModule,
GroupsModule,
RolesModule,
],
providers: [],
})
export class AppModule {}
users.module.ts
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { RolesService } from 'roles/roles.service';
import { UserSchema } from './schemas/user.schema';
import { RoleSchema } from 'roles/schemas/role.schema';
@Module({
imports: [
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]),
MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }]),
],
controllers: [UsersController],
providers: [UsersService, RolesService],
exports: [UsersService],
})
export class UsersModule {}
users.service.ts
import { Model } from 'mongoose';
import { ObjectID } from 'mongodb';
import { InjectModel } from '@nestjs/mongoose';
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { User } from './interfaces/user.interface';
@Injectable()
export class UsersService {
constructor(@InjectModel('User') private readonly userModel: Model<User>) {}
}
groups.module.ts
import { MongooseModule } from '@nestjs/mongoose';
import { GroupsController } from './groups.controller';
import { RolesService } from '../roles/roles.service';
import { GroupsService } from './groups.service';
import { GroupSchema } from './schemas/group.schema';
import { UserSchema } from '../users/schemas/user.schema';
import { RoleSchema } from '../roles/schemas/role.schema';
@Module({
imports: [
MongooseModule.forFeature([{ name: 'Group', schema: GroupSchema }]),
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]),
MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }]),
],
controllers: [GroupsController],
providers: [GroupsService, RolesService],
exports: [GroupsService],
})
groups.service.ts
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { ObjectID } from 'mongodb';
import { Model } from 'mongoose';
import { Group } from './interfaces/group.interface';
import { User } from '../users/interfaces/user.interface';
import { CreateGroupDto } from './dto/create-group.dto';
import { RolesDto } from 'roles/dto/roles.dto';
import { Role } from '../roles/interfaces/role.interface';
@Injectable()
export class GroupsService {
constructor(@InjectModel('Group') private readonly groupModel: Model<Group>,
@InjectModel('Role') private readonly roleModel: Model<Role>) {} }
roles.module.ts
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { RolesController } from './roles.controller';
import { RolesService } from './roles.service';
import { RoleSchema } from './schemas/role.schema';
import { UserSchema } from '../users/schemas/user.schema';
import { GroupSchema } from '../groups/schemas/group.schema';
@Module({
imports: [
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]),
MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }]),
MongooseModule.forFeature([{ name: 'Group', schema: GroupSchema }]),
],
controllers: [RolesController],
providers: [RolesService],
exports: [RolesService],
})
export class RolesModule {}
roles.service.ts
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { ObjectID } from 'mongodb';
import { Model } from 'mongoose';
import { Role } from './interfaces/role.interface';
import { User } from '../users/interfaces/user.interface';
import { Group } from '../groups/interfaces/group.interface';
import { CreateRoleDto } from './dto/create-role.dto';
import { RolesDto } from './dto/roles.dto';
@Injectable()
export class RolesService {
constructor( @InjectModel('Role') private readonly roleModel: Model<Role>,
@InjectModel('User') private readonly userModel: Model<User>,
@InjectModel('Group') private readonly groupModel: Model<Group> ) {} }
虽然用户和角色中的 DI 工作正常,但当我尝试在角色服务中导入组模型时出现错误。如果您发现任何错误,请告诉我,我遵循了来自组用户的相同模式,但遗憾的是看不到错误所在。
提前致谢。
更新:好的,我认为我的错误是当我尝试在模块外使用模块服务功能时。我的意思是我修改了(为了简化)我会这样修改代码:
users.module.ts
@Module({
imports: [
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]),
RolesModule,
],
controllers: [UsersController],
providers: [UsersService, RolesService],
exports: [UsersService],
})
export class UsersModule {}
users.controller.ts
export class UsersController {
constructor(private readonly usersService: UsersService,
private readonly rolesService: RolesService){}
async addRoles(@Param('id') id: string, @Body() userRolesDto: UserRolesDto): Promise<User> {
try {
return this.rolesService.setRoles(id, userRolesDto);
} catch (e){
const message = e.message.message;
if ( e.message.error === 'NOT_FOUND'){
throw new NotFoundException(message);
} else if ( e.message.error === 'ID_NOT_VALID'){
throw new BadRequestException(message);
}
}
}
}
roles.module.ts
@Module({
imports: [
MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }]),
],
controllers: [RolesController],
providers: [RolesService],
exports: [RolesService],
})
export class RolesModule {}
roles.service.ts
@Injectable()
export class RolesService {
userModel: any;
constructor( @InjectModel('Role') private readonly roleModel: Model<Role> ) {}
// SET USER ROLES
async setRoles(id: string, rolesDto: RolesDto): Promise<User> {
if ( !ObjectID.isValid(id) ){
throw new HttpException({error: 'ID_NOT_VALID', message: `ID ${id} is not valid`, status: HttpStatus.BAD_REQUEST}, 400);
}
try {
const date = moment().valueOf();
const resp = await this.userModel.updateOne({
_id: id,
}, {
$set: {
updated_at: date,
roles: rolesDto.roles,
},
});
if ( resp.nModified === 0 ){
throw new HttpException({ error: 'NOT_FOUND', message: `ID ${id} not found or entity not modified`, status: HttpStatus.NOT_FOUND}, 404);
} else {
let user = await this.userModel.findOne({ _id: id });
user = _.pick(user, ['_id', 'email', 'roles', 'created_at', 'updated_at']);
return user;
}
} catch (e) {
if ( e.message.error === 'NOT_FOUND' ){
throw new HttpException({ error: 'NOT_FOUND', message: `ID ${id} not found or entity not modified`, status: HttpStatus.NOT_FOUND}, 404);
} else {
throw new HttpException({error: 'ID_NOT_VALID', message: `ID ${id} is not valid`, status: HttpStatus.BAD_REQUEST}, 400);
}
}
}
就是这样,正如您所见,当我尝试使用 users.controller 中的 roles.service setRole 方法时,它 returns 给我一个错误:
Nest 无法解析 RolesService 的依赖项 (?)。请确保索引 [0] 处的参数在当前上下文中可用。
我不明白问题出在哪里,因为我已经在 roles.module 中注入角色模型,但它不理解。事实上,如果我不创建从 users.module 到此依赖项的调用,一切都会正常进行。
有什么建议吗?
(Whosebug的建议我已经红了,以后不会了)
我认为问题在于您多次导入同一个模型,例如:
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]
并且还多次提供相同的服务:
providers: [RolesService]
我不会注入模型本身,而是注入封装模型的相应服务。然后你 export
在其模块中的服务并在需要的地方导入模块。所以 RolesService
会注入 UsersSerivce
而不是 UserModel
.
使用您当前的设置,您会 运行 进入循环依赖。这可以用 fowardRef(() => UserService)
来处理,但应该尽可能避免,参见 circular dependency docs。但是,这是否可以避免取决于您的业务逻辑。
如果你没有循环依赖,那么例如导出你的 RolesService
@Module({
imports: [MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }])]
controllers: [RolesController],
providers: [RolesService],
exports: [RolesService],
})
export class RolesModule {}
并在任何你想使用 RolesService
的地方导入 RolesModule
,例如:
@Module({
imports: [
RolesModule,
MongooseModule.forFeature([{ name: 'User', schema: UserSchema }])
],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService],
})