# @repo/core 提供者类型详解 ## 提供者类型概览 | 类型 | 用途 | 示例 | |------|------|------| | ValueProvider | 提供静态值 | 配置、常量 | | ClassProvider | 提供类实例 | 服务类 | | FactoryProvider | 通过工厂函数创建 | 需要动态配置的服务 | | ExistingProvider | 别名映射 | 接口到实现的映射 | | ConstructorProvider | 类本身作为令牌 | 简化注册 | | LazyClassProvider | 延迟实例化类 | 重型服务 | | LazyFactoryProvider | 延迟调用工厂 | 按需加载配置 | ## ValueProvider 直接提供值,不进行实例化。 ```typescript interface ValueProvider { provide: InjectionTokenType useValue: T multi?: boolean } // 示例 - 始终使用 InjectionToken 确保类型安全 const API_URL = new InjectionToken('API_URL') const CONFIG_TOKEN = new InjectionToken('CONFIG_TOKEN') const VERSION = new InjectionToken('VERSION') { provide: API_URL, useValue: 'https://api.example.com' } { provide: CONFIG_TOKEN, useValue: { debug: true, timeout: 5000 } } { provide: VERSION, useValue: '1.0.0' } ``` **适用场景**: - 配置值 - 常量 - 已创建的实例 - 简单对象 ## ClassProvider 通过构造函数创建实例。 ```typescript interface ClassProvider { provide: InjectionTokenType useClass: Type multi?: boolean } // 示例 { provide: UserService, useClass: UserService } { provide: Logger, useClass: ConsoleLogger } { provide: IAuthService, useClass: JwtAuthService } ``` **适用场景**: - 服务类 - 接口到实现的映射 - 替换默认实现 ## FactoryProvider 通过工厂函数创建实例。 ```typescript interface FactoryProvider { provide: InjectionTokenType useFactory: (...deps: any[]) => T deps?: InjectionTokenType[] 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 创建到另一个令牌的别名。 ```typescript interface ExistingProvider { provide: InjectionTokenType useExisting: InjectionTokenType multi?: boolean } // 示例 - 使用 InjectionToken 确保类型安全 const LOGGER_TOKEN = new InjectionToken('Logger') { provide: LOGGER_TOKEN, useExisting: LoggerService } { provide: AbstractLogger, useExisting: ConsoleLogger } ``` **适用场景**: - 为同一服务提供多个令牌 - 向后兼容 - 接口别名 ## ConstructorProvider 类本身作为令牌和实现。 ```typescript interface ConstructorProvider { provide: Type multi?: boolean } // 示例 { provide: UserService } // 等价于 { provide: UserService, useClass: UserService } ``` **适用场景**: - 简化注册 - 类名即令牌 ## LazyClassProvider 延迟实例化,首次访问时才创建。 ```typescript interface LazyClassProvider { provide: InjectionTokenType useLazyClass: Type multi?: boolean } // 示例 { provide: HeavyAnalyticsService, useLazyClass: HeavyAnalyticsService } { provide: ReportGenerator, useLazyClass: ReportGenerator } ``` **适用场景**: - 重型服务(大量初始化开销) - 可能不会使用的服务 - 优化启动时间 ## LazyFactoryProvider 延迟调用工厂函数。 ```typescript interface LazyFactoryProvider { provide: InjectionTokenType useLazyFactory: (...deps: any[]) => T deps?: InjectionTokenType[] multi?: boolean } // 示例 - 使用 InjectionToken 确保类型安全 const LAZY_CONFIG = new InjectionToken('LAZY_CONFIG') { provide: LAZY_CONFIG, useLazyFactory: async () => { const response = await fetch('/api/config') return response.json() }, deps: [] } ``` **适用场景**: - 按需加载配置 - 延迟网络请求 - 条件初始化 ## Multi Provider 允许多个提供者注册到同一令牌。 ```typescript // 注册多个拦截器 { 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 ``` ## 常见模式 ### 环境配置 ```typescript import { InjectionToken } from '@repo/core' // 定义类型安全的令牌 const ENV = new InjectionToken('ENV') const API_URL = new InjectionToken('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) ``` ### 条件提供者 ```typescript const providers = [ process.env.USE_MOCK ? { provide: UserService, useClass: MockUserService } : { provide: UserService, useClass: RealUserService } ] ``` ### 工厂链 ```typescript 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] } ] ```