forked from datawhale/whale-town-end
Merge pull request 'feature/code-standard-auth-20260114' (#46) from feature/code-standard-auth-20260114 into main
Reviewed-on: datawhale/whale-town-end#46
This commit is contained in:
@@ -442,6 +442,190 @@ export class UsersBusinessService {
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 NestJS依赖注入检查(重要)
|
||||
|
||||
### 依赖注入完整性检查
|
||||
**在NestJS中,如果一个类(如Guard、Service、Controller)需要注入其他服务,必须确保该服务在模块的imports中可访问。**
|
||||
|
||||
### 常见依赖注入问题
|
||||
```typescript
|
||||
// ❌ 错误:JwtAuthGuard需要LoginCoreService,但模块未导入LoginCoreModule
|
||||
@Module({
|
||||
imports: [
|
||||
AuthModule, // AuthModule虽然导入了LoginCoreModule,但没有重新导出
|
||||
],
|
||||
providers: [
|
||||
JwtAuthGuard, // 错误:无法注入LoginCoreService
|
||||
],
|
||||
})
|
||||
export class AuthGatewayModule {}
|
||||
|
||||
@Injectable()
|
||||
export class JwtAuthGuard {
|
||||
constructor(
|
||||
private readonly loginCoreService: LoginCoreService, // 注入失败!
|
||||
) {}
|
||||
}
|
||||
|
||||
// ✅ 正确方案1:直接导入需要的Core模块
|
||||
@Module({
|
||||
imports: [
|
||||
AuthModule,
|
||||
LoginCoreModule, // 直接导入,使LoginCoreService可用
|
||||
],
|
||||
providers: [
|
||||
JwtAuthGuard, // 现在可以成功注入LoginCoreService
|
||||
],
|
||||
})
|
||||
export class AuthGatewayModule {}
|
||||
|
||||
// ✅ 正确方案2:在中间模块重新导出
|
||||
@Module({
|
||||
imports: [LoginCoreModule],
|
||||
exports: [LoginCoreModule], // 重新导出,让导入AuthModule的模块也能访问
|
||||
})
|
||||
export class AuthModule {}
|
||||
```
|
||||
|
||||
### 依赖注入检查规则
|
||||
|
||||
#### 1. 检查Provider的构造函数依赖
|
||||
```typescript
|
||||
// 对于每个Provider(Service、Guard、Interceptor等)
|
||||
@Injectable()
|
||||
export class SomeGuard {
|
||||
constructor(
|
||||
private readonly serviceA: ServiceA, // 依赖1
|
||||
private readonly serviceB: ServiceB, // 依赖2
|
||||
) {}
|
||||
}
|
||||
|
||||
// 检查清单:
|
||||
// ✓ ServiceA是否在当前模块的imports中?
|
||||
// ✓ ServiceB是否在当前模块的imports中?
|
||||
// ✓ 如果不在,是否需要添加对应的Module到imports?
|
||||
```
|
||||
|
||||
#### 2. 检查Module的导出完整性
|
||||
```typescript
|
||||
// ❌ 错误:导入了模块但没有导出,导致上层模块无法访问
|
||||
@Module({
|
||||
imports: [LoginCoreModule],
|
||||
providers: [LoginService],
|
||||
exports: [LoginService], // 只导出了LoginService,没有导出LoginCoreModule
|
||||
})
|
||||
export class AuthModule {}
|
||||
|
||||
// 如果上层模块需要直接使用LoginCoreService:
|
||||
@Module({
|
||||
imports: [AuthModule], // 无法访问LoginCoreService
|
||||
providers: [JwtAuthGuard], // JwtAuthGuard需要LoginCoreService,会失败
|
||||
})
|
||||
export class AuthGatewayModule {}
|
||||
|
||||
// ✅ 正确:根据需要导出Module
|
||||
@Module({
|
||||
imports: [LoginCoreModule],
|
||||
providers: [LoginService],
|
||||
exports: [
|
||||
LoginService,
|
||||
LoginCoreModule, // 导出Module,让上层也能访问
|
||||
],
|
||||
})
|
||||
export class AuthModule {}
|
||||
```
|
||||
|
||||
#### 3. 检查跨层依赖的模块导入
|
||||
```typescript
|
||||
// Gateway层的Guard直接依赖Core层Service的情况
|
||||
@Injectable()
|
||||
export class JwtAuthGuard {
|
||||
constructor(
|
||||
private readonly loginCoreService: LoginCoreService, // 直接依赖Core层
|
||||
) {}
|
||||
}
|
||||
|
||||
// 检查清单:
|
||||
// ✓ AuthGatewayModule是否导入了LoginCoreModule?
|
||||
// ✓ 如果通过AuthModule间接导入,AuthModule是否导出了LoginCoreModule?
|
||||
// ✓ 是否符合架构分层原则(Gateway可以直接依赖Core用于技术实现)?
|
||||
```
|
||||
|
||||
### 依赖注入检查步骤
|
||||
|
||||
1. **扫描所有Injectable类**
|
||||
- 找出所有使用@Injectable()装饰器的类
|
||||
- 包括Service、Guard、Interceptor、Pipe等
|
||||
|
||||
2. **分析构造函数依赖**
|
||||
- 检查每个类的constructor参数
|
||||
- 列出所有需要注入的服务
|
||||
|
||||
3. **检查Module的imports**
|
||||
- 确认每个依赖的服务是否在Module的imports中
|
||||
- 检查imports的Module是否导出了需要的服务
|
||||
|
||||
4. **验证依赖链完整性**
|
||||
- 如果A模块导入B模块,B模块导入C模块
|
||||
- 确认A模块是否能访问C模块的服务(取决于B是否导出C)
|
||||
|
||||
5. **检查常见错误模式**
|
||||
- Guard/Interceptor依赖Service但模块未导入
|
||||
- 中间模块导入但未导出,导致上层无法访问
|
||||
- 循环依赖问题
|
||||
|
||||
### 依赖注入错误识别
|
||||
|
||||
#### 典型错误信息
|
||||
```
|
||||
Nest can't resolve dependencies of the JwtAuthGuard (?).
|
||||
Please make sure that the argument LoginCoreService at index [0]
|
||||
is available in the AuthGatewayModule context.
|
||||
```
|
||||
|
||||
#### 错误分析流程
|
||||
```
|
||||
1. 识别问题类:JwtAuthGuard
|
||||
2. 识别缺失依赖:LoginCoreService(索引0)
|
||||
3. 识别所在模块:AuthGatewayModule
|
||||
4. 检查解决方案:
|
||||
├─ LoginCoreService在哪个Module中提供?
|
||||
│ └─ 答:LoginCoreModule
|
||||
├─ AuthGatewayModule是否导入了LoginCoreModule?
|
||||
│ └─ 否 → 需要添加到imports
|
||||
└─ 如果通过其他Module间接导入,该Module是否导出了LoginCoreModule?
|
||||
└─ 否 → 需要在中间Module的exports中添加
|
||||
```
|
||||
|
||||
### 依赖注入最佳实践
|
||||
|
||||
```typescript
|
||||
// ✅ 推荐:明确的依赖关系
|
||||
@Module({
|
||||
imports: [
|
||||
// 业务层模块
|
||||
AuthModule,
|
||||
// 直接需要的核心层模块(用于Guard等技术组件)
|
||||
LoginCoreModule,
|
||||
],
|
||||
controllers: [LoginController],
|
||||
providers: [JwtAuthGuard],
|
||||
exports: [JwtAuthGuard],
|
||||
})
|
||||
export class AuthGatewayModule {}
|
||||
|
||||
// ✅ 推荐:完整的导出链
|
||||
@Module({
|
||||
imports: [LoginCoreModule, UsersModule],
|
||||
providers: [LoginService],
|
||||
exports: [
|
||||
LoginService, // 导出自己的服务
|
||||
LoginCoreModule, // 导出依赖的模块(如果上层需要)
|
||||
],
|
||||
})
|
||||
export class AuthModule {}
|
||||
```
|
||||
|
||||
## 🔍 检查执行步骤
|
||||
|
||||
1. **识别当前模块的层级**
|
||||
@@ -475,7 +659,14 @@ export class UsersBusinessService {
|
||||
- Core层是否只包含技术实现
|
||||
- 是否有跨层职责混乱
|
||||
|
||||
6. **检查依赖关系**
|
||||
6. **🔥 检查依赖注入完整性(关键步骤)**
|
||||
- 扫描所有Injectable类的构造函数依赖
|
||||
- 检查Module的imports是否包含所有依赖的Module
|
||||
- 验证中间Module是否正确导出了需要的服务
|
||||
- 确认依赖链的完整性和可访问性
|
||||
- 识别并修复常见的依赖注入错误
|
||||
|
||||
7. **检查依赖关系**
|
||||
- Gateway层是否只依赖Business层
|
||||
- Business层是否只依赖Core层
|
||||
- Core层是否不依赖业务层
|
||||
|
||||
@@ -29,11 +29,14 @@ import { LoginController } from './login.controller';
|
||||
import { RegisterController } from './register.controller';
|
||||
import { JwtAuthGuard } from './jwt_auth.guard';
|
||||
import { AuthModule } from '../../business/auth/auth.module';
|
||||
import { LoginCoreModule } from '../../core/login_core/login_core.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
// 导入业务层模块
|
||||
AuthModule,
|
||||
// 导入核心层模块(JwtAuthGuard需要LoginCoreService)
|
||||
LoginCoreModule,
|
||||
],
|
||||
controllers: [
|
||||
// 网关层控制器
|
||||
|
||||
Reference in New Issue
Block a user