angular-di
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAngular Dependency Injection
Angular 依赖注入
Version: Angular 21 (2025)
Tags: DI, Services, Providers, Tokens, inject()
API Changes
API变更
This section documents recent version-specific API changes.
-
NEW: Functional injection with inject() — Preferred over constructor injection in modern Angular source
-
NEW: inject() with Optional decorator —
inject(Service, { optional: true }) -
NEW: inject() with SkipSelf —
inject(Service, { skipSelf: true }) -
NEW: Tree-shakable InjectionToken —
new InjectionToken<T>(desc, { providedIn: 'root' })
本部分记录了近期特定版本的API变更。
-
新增:使用inject()进行函数式注入——现代Angular中优先于构造函数注入使用 来源
-
新增:搭配Optional装饰器使用inject() ——
inject(Service, { optional: true }) -
新增:搭配SkipSelf使用inject() ——
inject(Service, { skipSelf: true }) -
新增:支持Tree-shaking的InjectionToken ——
new InjectionToken<T>(desc, { providedIn: 'root' })
Best Practices
最佳实践
- Use providedIn: 'root' for singleton services
ts
@Injectable({ providedIn: 'root' })
export class LoggerService {
log(message: string) { console.log(message); }
}- Use inject() function for cleaner code
ts
@Component({})
export class MyComponent {
private service = inject(MyService);
private router = inject(Router);
}- Use InjectionToken for non-class dependencies
ts
export const API_URL = new InjectionToken<string>('apiUrl');
providers: [
{ provide: API_URL, useValue: 'https://api.example.com' }
]
constructor(@Inject(API_URL) private apiUrl: string) {}- Use factory providers for complex instantiation
ts
providers: [
{
provide: AuthService,
useFactory: (http: HttpClient, config: AppConfig) => {
return new AuthService(http, config.apiUrl);
},
deps: [HttpClient, APP_CONFIG]
}
]- Use multi providers for multiple implementations
ts
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: LogInterceptor, multi: true }
]- Use @Optional for optional dependencies
ts
constructor(@Optional() private logger: LoggerService) {
this.logger?.log('Optional dependency');
}- Use @SkipSelf to avoid self-injection
ts
constructor(@SkipSelf() @Optional() private parent: ParentService) {}- Use forwardRef for circular dependencies
ts
constructor(@Inject(forwardRef(() => ParentService)) private parent: ParentService) {}- Use hierarchical injectors for scoping
ts
// Component-level provider
@Component({
providers: [MyService]
})
export class MyComponent {}
// Lazy-loaded module provider
@Injectable({ providedIn: MyModule })
export class MyService {}- Use interface injection pattern
ts
export interface CacheInterface {
get(key: string): any;
}
export const CACHE_TOKEN = new InjectionToken<CacheInterface>('cache');- Use providedIn: 'any' for lazy-loaded services
ts
@Injectable({ providedIn: 'any' })
export class LazyService {}- 单例服务使用providedIn: 'root'
ts
@Injectable({ providedIn: 'root' })
export class LoggerService {
log(message: string) { console.log(message); }
}- 使用inject()函数让代码更简洁
ts
@Component({})
export class MyComponent {
private service = inject(MyService);
private router = inject(Router);
}- 非类依赖使用InjectionToken
ts
export const API_URL = new InjectionToken<string>('apiUrl');
providers: [
{ provide: API_URL, useValue: 'https://api.example.com' }
]
constructor(@Inject(API_URL) private apiUrl: string) {}- 复杂实例化场景使用factory providers
ts
providers: [
{
provide: AuthService,
useFactory: (http: HttpClient, config: AppConfig) => {
return new AuthService(http, config.apiUrl);
},
deps: [HttpClient, APP_CONFIG]
}
]- 多实现场景使用multi providers
ts
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: LogInterceptor, multi: true }
]- 可选依赖使用@Optional
ts
constructor(@Optional() private logger: LoggerService) {
this.logger?.log('Optional dependency');
}- 使用@SkipSelf避免自注入
ts
constructor(@SkipSelf() @Optional() private parent: ParentService) {}- 循环依赖使用forwardRef
ts
constructor(@Inject(forwardRef(() => ParentService)) private parent: ParentService) {}- 做作用域控制使用层级注入器
ts
// 组件级别provider
@Component({
providers: [MyService]
})
export class MyComponent {}
// 懒加载模块provider
@Injectable({ providedIn: MyModule })
export class MyService {}- 使用接口注入模式
ts
export interface CacheInterface {
get(key: string): any;
}
export const CACHE_TOKEN = new InjectionToken<CacheInterface>('cache');- 懒加载服务使用providedIn: 'any'
ts
@Injectable({ providedIn: 'any' })
export class LazyService {}