ค้นหาเว็บไซต์

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

บทความที่เกี่ยวข้อง