fix: 添加skills

This commit is contained in:
imeepos
2026-01-29 15:13:27 +08:00
parent b716198d4b
commit 6279752f23
16 changed files with 5462 additions and 27 deletions

View File

@@ -0,0 +1,340 @@
---
name: repo-core-di
description: "@repo/core 依赖注入框架使用指南。当需要创建注入器、注册提供者、使用装饰器(@Injectable, @Inject, @Optional等)、处理生命周期(OnInit, OnDestroy)、或解决循环依赖时使用此技能。适用于:(1) 创建和配置注入器层次结构 (2) 注册各类提供者(Value/Class/Factory/Lazy) (3) 使用参数装饰器控制注入行为 (4) 实现服务生命周期管理 (5) 使用 InjectionToken 和 ForwardRef"
---
# @repo/core 依赖注入框架
## 核心概念
@repo/core 提供企业级依赖注入框架,支持层次化注入器、多种提供者类型、生命周期管理。
### 注入器层次结构
```
Root (根注入器)
└── Platform (平台注入器)
└── Application (应用注入器)
└── Feature (特性注入器)
```
## 快速开始
### 创建注入器
```typescript
import { EnvironmentInjector, Injectable, InjectionToken } from '@repo/core'
// 定义类型安全的令牌
const API_URL = new InjectionToken<string>('API_URL')
// 创建根注入器
const rootInjector = EnvironmentInjector.createRootInjector([
{ provide: API_URL, useValue: 'https://api.example.com' }
])
// 创建应用注入器(继承根注入器)
const appInjector = EnvironmentInjector.createApplicationInjector([
UserService,
{ provide: LoggerService, useClass: LoggerService }
])
// 初始化(执行所有 @OnInit
await appInjector.init()
// 获取服务
const userService = appInjector.get(UserService)
```
### 使用 @Injectable 装饰器
```typescript
import { Injectable } from '@repo/core'
// providedIn: 'root' - 单例,自动注册到根注入器
@Injectable({ providedIn: 'root' })
class ConfigService {
apiUrl = 'https://api.example.com'
}
// providedIn: 'auto' - 不自动注册到根注入器,可在任何注入器中被按需解析
// 推荐用于请求级服务
@Injectable({ providedIn: 'auto' })
class RequestScopedService {
// 每次请求创建新实例
}
// 使用工厂函数
@Injectable({
providedIn: 'root',
useFactory: (config: ConfigService) => new ApiClient(config.apiUrl),
deps: [ConfigService]
})
class ApiClient {
constructor(public baseUrl: string) {}
}
```
## 提供者类型
### 值提供者 (ValueProvider)
```typescript
const API_URL = new InjectionToken<string>('API_URL')
const CONFIG_TOKEN = new InjectionToken<AppConfig>('CONFIG_TOKEN')
{ provide: API_URL, useValue: 'https://api.example.com' }
{ provide: CONFIG_TOKEN, useValue: { debug: true, timeout: 5000 } }
```
### 类提供者 (ClassProvider)
```typescript
{ provide: UserService, useClass: UserService }
{ provide: Logger, useClass: ConsoleLogger } // 接口映射到实现
```
### 工厂提供者 (FactoryProvider)
```typescript
{
provide: DatabaseConnection,
useFactory: (config: ConfigService) => {
return new DatabaseConnection(config.dbUrl)
},
deps: [ConfigService]
}
```
### 别名提供者 (ExistingProvider)
```typescript
const LOGGER_TOKEN = new InjectionToken<Logger>('Logger')
{ provide: LOGGER_TOKEN, useExisting: LoggerService }
```
### 延迟提供者 (LazyProvider)
```typescript
const LAZY_CONFIG = new InjectionToken<AppConfig>('LAZY_CONFIG')
// 延迟类 - 首次访问时才实例化
{ provide: HeavyService, useLazyClass: HeavyService }
// 延迟工厂
{ provide: LAZY_CONFIG, useLazyFactory: () => loadConfig(), deps: [] }
```
### 多值提供者 (Multi Provider)
```typescript
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
{ provide: HTTP_INTERCEPTORS, useClass: LoggingInterceptor, multi: true }
// 获取时返回数组
const interceptors = injector.get(HTTP_INTERCEPTORS) // [AuthInterceptor, LoggingInterceptor]
```
## 参数装饰器
### @Inject - 显式指定注入令牌
```typescript
const API_URL = new InjectionToken<string>('API_URL')
class UserController {
constructor(
@Inject(UserService) private userService: UserService,
@Inject(API_URL) private apiUrl: string
) {}
}
```
### @Optional - 可选注入
```typescript
class NotificationService {
constructor(
@Optional(EmailService) private email?: EmailService // 不存在时为 null
) {}
}
```
### @Self - 仅在当前注入器查找
```typescript
class ChildComponent {
constructor(
@Self(LocalService) private local: LocalService // 不查找父注入器
) {}
}
```
### @SkipSelf - 跳过当前注入器
```typescript
class ChildService {
constructor(
@SkipSelf(ParentService) private parent: ParentService // 从父注入器开始查找
) {}
}
```
### @Host - 在宿主注入器查找
```typescript
class DirectiveService {
constructor(
@Host(HostService) private host: HostService
) {}
}
```
## 生命周期管理
### @OnInit 装饰器
```typescript
import { Injectable, OnInit } from '@repo/core'
@Injectable({ providedIn: 'root' })
class DatabaseService implements OnInit {
private connection: Connection
@OnInit()
async onInit() {
this.connection = await this.connect()
console.log('Database connected')
}
private async connect() {
// 连接逻辑
}
}
```
### OnDestroy 接口
```typescript
import { Injectable, OnDestroy } from '@repo/core'
@Injectable({ providedIn: 'root' })
class CacheService implements OnDestroy {
async onDestroy() {
await this.flush()
console.log('Cache flushed')
}
}
// 销毁注入器时自动调用
await injector.destroy()
```
### APP_INITIALIZER - 应用初始化器
```typescript
import { APP_INITIALIZER, InjectionToken } from '@repo/core'
const appInjector = EnvironmentInjector.createApplicationInjector([
{
provide: APP_INITIALIZER,
useValue: {
provide: new InjectionToken('DB_INIT'),
deps: [ConfigService],
init: async () => {
await initDatabase()
}
},
multi: true
},
{
provide: APP_INITIALIZER,
useValue: {
provide: new InjectionToken('CACHE_INIT'),
deps: [new InjectionToken('DB_INIT')], // 依赖 DB_INIT
init: async () => {
await initCache()
}
},
multi: true
}
])
// 按依赖顺序执行初始化器
await appInjector.init()
```
## InjectionToken
```typescript
import { InjectionToken } from '@repo/core'
// 创建类型安全的令牌
const API_URL = new InjectionToken<string>('API_URL')
const CONFIG = new InjectionToken<AppConfig>('CONFIG')
const LOGGER_LEVEL = new InjectionToken<LoggerLevel>('LOGGER_LEVEL')
// 注册
const injector = EnvironmentInjector.createRootInjector([
{ provide: API_URL, useValue: 'https://api.example.com' },
{ provide: CONFIG, useValue: { debug: true } }
])
// 获取(类型安全)
const url: string = injector.get(API_URL)
const config: AppConfig = injector.get(CONFIG)
```
## ForwardRef - 解决循环依赖
```typescript
import { Injectable, Inject, forwardRef } from '@repo/core'
@Injectable({ providedIn: 'root' })
class ServiceA {
constructor(
@Inject(forwardRef(() => ServiceB)) private serviceB: ServiceB
) {}
}
@Injectable({ providedIn: 'root' })
class ServiceB {
constructor(
@Inject(forwardRef(() => ServiceA)) private serviceA: ServiceA
) {}
}
```
## 便捷工厂函数
```typescript
import {
createRootInjector,
createPlatformInjector,
createApplicationInjector,
createFeatureInjector
} from '@repo/core'
// 简化创建
const root = createRootInjector([...providers])
const platform = createPlatformInjector([...providers])
const app = createApplicationInjector([...providers])
const feature = createFeatureInjector([...providers], parentInjector)
```
## 最佳实践
1. **使用 providedIn: 'root'** - 大多数服务应该是单例
2. **避免循环依赖** - 使用 ForwardRef 仅作为最后手段
3. **使用 InjectionToken** - 为非类类型创建类型安全令牌
4. **实现 OnDestroy** - 清理资源(连接、订阅等)
5. **使用 APP_INITIALIZER** - 管理复杂的初始化顺序
6. **延迟加载** - 对重型服务使用 useLazyClass/useLazyFactory
## 参考文档
- 详细 API 参考:见 [references/api.md](references/api.md)
- 提供者类型详解:见 [references/providers.md](references/providers.md)
- 请求级注入器:见 [references/request-scoped-injector.md](references/request-scoped-injector.md) - HTTP 请求隔离、CURRENT_USER 注入、Controller 生命周期
- 错误处理系统:见 [references/errors.md](references/errors.md) - 预定义错误类、ErrorFactory、ErrorSerializer