--- 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('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('API_URL') const CONFIG_TOKEN = new InjectionToken('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') { provide: LOGGER_TOKEN, useExisting: LoggerService } ``` ### 延迟提供者 (LazyProvider) ```typescript const LAZY_CONFIG = new InjectionToken('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('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('API_URL') const CONFIG = new InjectionToken('CONFIG') const LOGGER_LEVEL = new InjectionToken('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