typescript - Angular 2 อินเทอร์เฟซที่สามารถฉีดได้?
วันนี้ฉันสะดุดกับบางสิ่งที่ฉันไม่คิดว่าจะสร้างปัญหาให้ฉัน
ใน Java และ Spring ฉันสามารถประกาศบีนสองตัวที่ทั้งคู่ใช้อินเทอร์เฟซที่กำหนดได้ ในขณะที่ในคลาสอื่นที่มีการฉีดพวกมันเข้ามา ฉันทำงานเพียงกับอินเทอร์เฟซเท่านั้น; นี่คือสิ่งที่ฉันชอบเกี่ยวกับ IoC: คุณไม่จำเป็นต้องรู้จริง ๆ ว่าคุณกำลังทำงานกับวัตถุอะไร เพียงแค่รู้ว่ามันเป็น ประเภท ของมัน
ดังนั้นในโปรแกรม Angular2/Typescript เล็ก ๆ ของฉัน ฉันกำลังพยายามทำสิ่งเดียวกัน:
webapp.module.ts:
...
import { WebAppConfigurationService } from './app/services/webapp.configuration.service';
@NgModule({
...
providers: [WebAppConfigurationService]
})
export class AppModule { }
tnsapp.module.ts:
...
import { TnsConfigurationService } from './services/tns.configuration.service';
@NgModule({
...
providers: [TnsConfigurationService]
})
export class AppModule { }
ทั้งสองโมดูลนี้ใช้ผู้ให้บริการที่แตกต่างกัน: TnsConfigurationService หรือ WebAppConfigurationService.
อย่างไรก็ตาม บริการ @Injectable ทั้งสองนี้ใช้ส่วนติดต่อเดียวกัน:
การกำหนดค่า.อินเทอร์เฟซ:
export interface IConfigurationService {
...
}
สุดท้าย ในหนึ่งในคอมโพเนนต์ของฉัน ฉันใช้ injectable ที่จัดเตรียมโดยหนึ่งในโมดูลเหล่านี้ที่ฉันได้แสดงให้คุณดูตอนต้น:
import { IConfigurationService } from './configuration.interface';
export class HeroesService {
constructor(private configurationService: IConfigurationService) { }
}
ความคาดหวังของฉันคือส่วนประกอบตัวสุดท้ายนี้จะถูกฉีดด้วยเซอร์วิสที่ถูกต้อง แม้ว่าพารามิเตอร์จะกำหนดเฉพาะอินเทอร์เฟซอย่างชัดเจน แน่นอนว่าฉันได้รับข้อผิดพลาด ("ข้อผิดพลาด: ไม่สามารถแก้ไขพารามิเตอร์ทั้งหมดสำหรับ HeroesService ได้")
ตอนนี้ ผม/ฉันไม่ได้คาดหวังว่าวิธีแก้ปัญหานี้จะง่ายเพราะมันฟังดูเหมือนเป็นความขาดแคลนทางสถาปัตยกรรม แต่บางทีใครสักคนอาจชี้ทางให้ผม/ฉันไปสู่การออกแบบทางเลือกได้ไหม?
คำตอบ #1
เพื่อให้ผู้ให้บริการถูกฉีดเข้าไปได้ จะต้องลงทะเบียนเป็นผู้ให้บริการ ไม่มีผู้ให้บริการ IConfigurationService และมันไม่สามารถเป็นผู้ให้บริการได้ เพราะอินเทอร์เฟซไม่ปรากฏอยู่ในโค้ด JS ที่คอมไพล์แล้ว
แนวปฏิบัติทั่วไปสำหรับอินเทอร์เฟซที่ถูกตั้งใจให้ใช้เป็นโทเค็นของผู้ให้บริการคือการเป็นคลาสนามธรรม:
abstract class ConfigurationService { ... }
@Injectable()
class WebAppConfigurationService extends ConfigurationService { ... }
...
providers: [{ provide: ConfigurationService, useClass: WebAppConfigurationService }]
...
สูตรนี้มักถูกใช้งานโดย Angular 2 เอง เช่น คลาสนามธรรม NgLocalization และการใช้งานจริง NgLocaleLocalization
