NestJS中如何根据用户角色条件实例化对应Service提供者
解决方案
你的核心问题在于工厂函数直接返回服务类而非实例,且未利用Nest的依赖注入容器自动解析服务的依赖项。可以通过ModuleRef动态创建服务实例,让Nest自动处理依赖注入逻辑。
修改步骤
1. 更新工厂函数,使用ModuleRef创建实例
修改user-service.factory.ts,注入ModuleRef并通过它生成对应服务的实例:
import { ModuleRef, UnauthorizedException } from '@nestjs/core'; import { Request } from 'express'; import { JwtService } from './jwt.service'; import { RolesEnum } from './roles.enum'; import { UserAdminService } from './user-admin.service'; import { UserSuperAdminService } from './user-super-admin.service'; export function UserServiceFactory(request: Request, moduleRef: ModuleRef) { // 处理缺失或无效的授权头 const authHeader = request.headers['authorization']; if (!authHeader || !authHeader.startsWith('Bearer ')) { throw new UnauthorizedException('授权头缺失或格式无效'); } const token = authHeader.split(' ')[1]; const { realm_access } = JwtService.parseJwt(token); // 验证令牌角色字段合法性 if (!realm_access?.roles) { throw new UnauthorizedException('令牌声明无效'); } // 根据角色创建对应服务实例 if (realm_access.roles.includes(RolesEnum.SuperAdmin)) { return moduleRef.create(UserSuperAdminService); } else { return moduleRef.create(UserAdminService); } }
2. 调整模块配置,注入ModuleRef并注册服务
修改user.module.ts,将两个服务类添加到providers数组,并在工厂配置中注入ModuleRef:
import { Module } from '@nestjs/common'; import { UserController } from './user.controller'; import { UserAdminService } from './user-admin.service'; import { UserSuperAdminService } from './user-super-admin.service'; import { UserServiceFactory } from './user-service.factory'; import { ModuleRef, REQUEST } from '@nestjs/core'; @Module({ controllers: [UserController], providers: [ // 必须注册服务类,让ModuleRef能获取到它们 UserAdminService, UserSuperAdminService, { provide: 'UserService', inject: [REQUEST, ModuleRef], // 注入REQUEST和ModuleRef useFactory: UserServiceFactory, }, ], }) export class UserModule {}
3. 控制器代码保持不变
你的user.controller.ts无需修改,Nest会自动注入动态创建的服务实例:
constructor( @Inject("UserService") private readonly userService: UserServiceInterface ) {}
关键说明
ModuleRef.create()方法会自动解析服务类构造函数中的所有依赖项(只要这些依赖已在Nest容器中注册),并返回完整的服务实例- 必须将
UserAdminService和UserSuperAdminService添加到模块的providers数组,否则ModuleRef无法找到并创建实例 - 新增的异常处理逻辑,避免因无效令牌或缺失授权头导致的运行时崩溃
内容的提问来源于stack exchange,提问作者Vinícius Santos de Pontes
相关产品推荐
相关产品推荐

