Angular中如何实现类似Spring的接口多实现类数组形式依赖注入
可以实现,核心是借助Angular依赖注入的multi提供者配置就能达到和Spring完全一致的效果。需要注意TypeScript的接口仅在编译期存在、运行时会被擦除,所以不能直接用接口作为注入标识,需要搭配InjectionToken作为统一的注入令牌使用,具体实现步骤如下:
1. 定义基础接口和注入令牌
// vehicle.interface.ts export interface Vehicle { runs(): void; } // vehicle.token.ts import { InjectionToken } from '@angular/core'; import { Vehicle } from './vehicle.interface'; // 定义统一的注入令牌,作为所有Vehicle实现的注入标识 export const VEHICLES = new InjectionToken<Vehicle[]>('vehicles token');
2. 编写接口实现类
// car.service.ts import { Injectable } from '@angular/core'; import { Vehicle } from './vehicle.interface'; @Injectable() export class Car implements Vehicle { runs(): void { console.log('Car is running'); } }
// bike.service.ts import { Injectable } from '@angular/core'; import { Vehicle } from './vehicle.interface'; @Injectable() export class Bike implements Vehicle { runs(): void { console.log('Bike is running'); } }
3. 注册所有实现类
在对应模块(或Angular14+的standalone组件)的providers中注册所有实现,必须添加multi: true配置,表示该令牌允许绑定多个提供者:
// app.module.ts(业务模块也可以) import { NgModule } from '@angular/core'; import { VEHICLES } from './vehicle.token'; import { Car } from './car.service'; import { Bike } from './bike.service'; @NgModule({ providers: [ { provide: VEHICLES, useClass: Car, multi: true }, { provide: VEHICLES, useClass: Bike, multi: true }, // 后续新增Vehicle实现,仅需在此处加一行注册即可,无需修改业务逻辑代码 ] }) export class AppModule { }
4. 业务代码中注入使用
// some.service.ts import { Injectable, Inject } from '@angular/core'; import { VEHICLES } from './vehicle.token'; import { Vehicle } from './vehicle.interface'; @Injectable() export class SomeService { // 直接注入所有Vehicle实现类的实例数组 constructor(@Inject(VEHICLES) private vehicles: Vehicle[]) {} otherMethod(): void { this.vehicles.forEach(vehicle => vehicle.runs()); } }
该实现完全符合开闭原则,后续新增接口实现不需要修改现有业务逻辑,和Spring中注入同接口所有实现类列表的特性效果完全一致。
内容的提问来源于stack exchange,提问作者sam
相关产品推荐
相关产品推荐

