6.3 KiB
6.3 KiB
@repo/core 提供者类型详解
提供者类型概览
| 类型 | 用途 | 示例 |
|---|---|---|
| ValueProvider | 提供静态值 | 配置、常量 |
| ClassProvider | 提供类实例 | 服务类 |
| FactoryProvider | 通过工厂函数创建 | 需要动态配置的服务 |
| ExistingProvider | 别名映射 | 接口到实现的映射 |
| ConstructorProvider | 类本身作为令牌 | 简化注册 |
| LazyClassProvider | 延迟实例化类 | 重型服务 |
| LazyFactoryProvider | 延迟调用工厂 | 按需加载配置 |
ValueProvider
直接提供值,不进行实例化。
interface ValueProvider<T> {
provide: InjectionTokenType<T>
useValue: T
multi?: boolean
}
// 示例 - 始终使用 InjectionToken 确保类型安全
const API_URL = new InjectionToken<string>('API_URL')
const CONFIG_TOKEN = new InjectionToken<AppConfig>('CONFIG_TOKEN')
const VERSION = new InjectionToken<string>('VERSION')
{ provide: API_URL, useValue: 'https://api.example.com' }
{ provide: CONFIG_TOKEN, useValue: { debug: true, timeout: 5000 } }
{ provide: VERSION, useValue: '1.0.0' }
适用场景:
- 配置值
- 常量
- 已创建的实例
- 简单对象
ClassProvider
通过构造函数创建实例。
interface ClassProvider<T> {
provide: InjectionTokenType<T>
useClass: Type<T>
multi?: boolean
}
// 示例
{ provide: UserService, useClass: UserService }
{ provide: Logger, useClass: ConsoleLogger }
{ provide: IAuthService, useClass: JwtAuthService }
适用场景:
- 服务类
- 接口到实现的映射
- 替换默认实现
FactoryProvider
通过工厂函数创建实例。
interface FactoryProvider<T> {
provide: InjectionTokenType<T>
useFactory: (...deps: any[]) => T
deps?: InjectionTokenType<any>[]
multi?: boolean
}
// 示例
{
provide: DatabaseConnection,
useFactory: (config: ConfigService) => {
return new DatabaseConnection({
host: config.dbHost,
port: config.dbPort,
database: config.dbName
})
},
deps: [ConfigService]
}
// 异步工厂
{
provide: RemoteConfig,
useFactory: async (http: HttpClient) => {
const config = await http.get('/config')
return new RemoteConfig(config)
},
deps: [HttpClient]
}
适用场景:
- 需要复杂初始化逻辑
- 依赖运行时配置
- 条件创建实例
- 异步初始化
ExistingProvider
创建到另一个令牌的别名。
interface ExistingProvider<T> {
provide: InjectionTokenType<T>
useExisting: InjectionTokenType<T>
multi?: boolean
}
// 示例 - 使用 InjectionToken 确保类型安全
const LOGGER_TOKEN = new InjectionToken<Logger>('Logger')
{ provide: LOGGER_TOKEN, useExisting: LoggerService }
{ provide: AbstractLogger, useExisting: ConsoleLogger }
适用场景:
- 为同一服务提供多个令牌
- 向后兼容
- 接口别名
ConstructorProvider
类本身作为令牌和实现。
interface ConstructorProvider<T> {
provide: Type<T>
multi?: boolean
}
// 示例
{ provide: UserService }
// 等价于
{ provide: UserService, useClass: UserService }
适用场景:
- 简化注册
- 类名即令牌
LazyClassProvider
延迟实例化,首次访问时才创建。
interface LazyClassProvider<T> {
provide: InjectionTokenType<T>
useLazyClass: Type<T>
multi?: boolean
}
// 示例
{ provide: HeavyAnalyticsService, useLazyClass: HeavyAnalyticsService }
{ provide: ReportGenerator, useLazyClass: ReportGenerator }
适用场景:
- 重型服务(大量初始化开销)
- 可能不会使用的服务
- 优化启动时间
LazyFactoryProvider
延迟调用工厂函数。
interface LazyFactoryProvider<T> {
provide: InjectionTokenType<T>
useLazyFactory: (...deps: any[]) => T
deps?: InjectionTokenType<any>[]
multi?: boolean
}
// 示例 - 使用 InjectionToken 确保类型安全
const LAZY_CONFIG = new InjectionToken<AppConfig>('LAZY_CONFIG')
{
provide: LAZY_CONFIG,
useLazyFactory: async () => {
const response = await fetch('/api/config')
return response.json()
},
deps: []
}
适用场景:
- 按需加载配置
- 延迟网络请求
- 条件初始化
Multi Provider
允许多个提供者注册到同一令牌。
// 注册多个拦截器
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
{ provide: HTTP_INTERCEPTORS, useClass: LoggingInterceptor, multi: true }
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }
// 获取时返回数组
const interceptors = injector.get(HTTP_INTERCEPTORS)
// [AuthInterceptor实例, LoggingInterceptor实例, ErrorInterceptor实例]
适用场景:
- 插件系统
- 中间件/拦截器
- 事件处理器
- 验证器集合
提供者选择决策树
需要提供什么?
├── 静态值/配置 → ValueProvider
├── 类实例
│ ├── 简单实例化 → ClassProvider 或 ConstructorProvider
│ ├── 需要复杂初始化 → FactoryProvider
│ ├── 延迟加载 → LazyClassProvider
│ └── 别名/映射 → ExistingProvider
├── 动态值
│ ├── 同步创建 → FactoryProvider
│ └── 延迟创建 → LazyFactoryProvider
└── 多个实现 → 任意类型 + multi: true
常见模式
环境配置
import { InjectionToken } from '@repo/core'
// 定义类型安全的令牌
const ENV = new InjectionToken<string>('ENV')
const API_URL = new InjectionToken<string>('API_URL')
const providers = [
{ provide: ENV, useValue: process.env.NODE_ENV },
{
provide: API_URL,
useFactory: (env: string) => {
return env === 'production'
? 'https://api.prod.com'
: 'https://api.dev.com'
},
deps: [ENV]
}
]
// 获取时类型安全
const apiUrl: string = injector.get(API_URL)
条件提供者
const providers = [
process.env.USE_MOCK
? { provide: UserService, useClass: MockUserService }
: { provide: UserService, useClass: RealUserService }
]
工厂链
const providers = [
{ provide: ConfigService, useClass: ConfigService },
{
provide: DatabaseService,
useFactory: (config: ConfigService) => new DatabaseService(config),
deps: [ConfigService]
},
{
provide: UserRepository,
useFactory: (db: DatabaseService) => new UserRepository(db),
deps: [DatabaseService]
}
]