简体   繁体   English

NestJS Nest无法解析RolesService的依赖关系(+,+ ,?)

[英]NestJS Nest can't resolve dependencies of the RolesService (+, +, ?)

Hi I'm programming using the NestJS framework (with MongoDB) and have build some modules now. 嗨,我正在使用NestJS框架(使用MongoDB)进行编程,现在已经构建了一些模块。 When I try to import a model from another module it returns this error: 当我尝试从另一个模块导入模型时,它返回此错误:

Nest can't resolve dependencies of the RolesService (+, +, ?). Nest无法解析RolesService(+,+ ,?)的依赖关系。

Now, I've implemented the code like this: 现在,我已经实现了这样的代码:

app.module.ts 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 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 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 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 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 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 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> ) {} }

While the DI in the users and roles works fine, the error arise when I try to import the Group Model in the roles service. 虽然用户和角色中的DI工作正常,但当我尝试在角色服务中导入组模型时会出现错误。 Please tell me if you see anything wrong, I've follow the same schema from users with groups but unfortunately can't see where the error lives. 请告诉我,如果您发现任何错误,我会从具有组的用户那里遵循相同的架构,但遗憾的是无法查看错误的存在位置。

Thanks in advance. 提前致谢。

UPDATE: OK I think my error is when I try to use a module service function outside the module. 更新:好的我认为我的错误是当我尝试在模块外部使用模块服务功能时。 I mean I modified (in order to simplify) I'll modify the code this way: 我的意思是我修改了(为了简化)我将以这种方式修改代码:

users.module.ts 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 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 roles.module.ts

@Module({
    imports: [
      MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }]),
    ],
    controllers: [RolesController],
    providers: [RolesService],
    exports: [RolesService],
  })

export class RolesModule {}

roles.service.ts 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);
          }
        }
    }

That's it, as you can see when I try to use from users.controller the roles.service setRole method it returns me an error: 就是这样,正如你可以看到当我尝试使用users.controller中的roles.service setRole方法时,它会返回一个错误:

Nest can't resolve dependencies of the RolesService (?). Nest无法解析RolesService(?)的依赖关系。 Please make sure that the argument at index [0]is available in the current context. 请确保索引[0]处的参数在当前上下文中可用。

I don't understand where the problem is because I'm injecting the Role model in the roles.module already and it don't understand it. 我不明白问题出在哪里,因为我已经在roles.module中注入了Role模型而且它不理解它。 In fact if I don't create the call from users.module to this dependency everything goes fine. 事实上,如果我不创建从users.module到这个依赖项的调用一切都很好。

Any tip? 有提示吗?

(I've red the suggestion from stackoverflow, I'll don't do it again) (我已经从stackoverflow中删除了建议,我不再这样做了)

I think the problem is that you're importing the same model multiple times, like: 我认为问题在于您多次导入相同的模型,例如:

MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]

and also providing the same service multiple times: 并多次提供相同的服务:

providers: [RolesService]

I would not inject the models themselves but rather the corresponding services that encapsulate the model. 我不会自己注入模型,而是封装模型的相应服务。 Then you export the service in its module and import the module where needed. 然后在其模块中export服务并在需要的地方导入模块。 So the RolesService would inject the UsersSerivce instead of the UserModel . 因此RolesService会注入UsersSerivce而不是UserModel

With your current setup, you would run into circular dependencies though. 使用当前的设置,您将遇到循环依赖。 This can be handled with fowardRef(() => UserService) but should be avoided if possible, see the circular dependency docs . 这可以使用fowardRef(() => UserService)处理,但如果可能应该避免,请参阅循环依赖文档 If this is avoidable depends on your business logic however. 如果这是可以避免的,则取决于您的业务逻辑。

If you don't have circular dependencies then for example export your RolesService 如果您没有循环依赖关系,那么例如导出您的RolesService

@Module({
    imports: [MongooseModule.forFeature([{ name: 'Role', schema: RoleSchema }])]
    controllers: [RolesController],
    providers: [RolesService],
    exports: [RolesService],
  })

export class RolesModule {}

and import the RolesModule wherever you want to use the RolesService , eg: 并在任何想要使用RolesModule地方导入RolesService ,例如:

@Module({
    imports: [
      RolesModule,
      MongooseModule.forFeature([{ name: 'User', schema: UserSchema }])
    ],
    controllers: [UsersController],
    providers: [UsersService],
    exports: [UsersService],
  })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM