angular學習之聊聊依賴注入

2022-05-19 22:00:33
什麼是依賴注入?本篇文章帶大家瞭解一下中的依賴注入(DI),詳細介紹一下AngularDI框架的兩個核心概念:注入器 Injectors和提供者 Provider,希望對大家有所幫助!

angular中的依賴注入(DI)

1、概述

依賴注入 ( Dependency Injection ) 簡稱DI,是物件導向程式設計中的一種設計原則,用來減少程式碼之間的耦合度。【相關教學推薦:《》】

class MailService {
  constructor(APIKEY) {}
}

class EmailSender {
  mailService: MailService
  constructor() {
    this.mailService = new MailService("APIKEY1234567890")
  }

  sendMail(mail) {
    this.mailService.sendMail(mail)
  }
}

const emailSender = new EmailSender()
emailSender.sendMail(mail)

EmailSender 類執行時要使用 MailService 類,EmailSender 類依賴 MailService 類,MailService 類是 EmailSender 類的依賴項。

以上寫法的耦合度太高,程式碼並不健壯。如果 MailService 類改變了引數的傳遞方式,在 EmailSender 類中的寫法也要跟著改變。

class EmailSender {
  mailService: MailService
  constructor(mailService: MailService) {
    this.mailService = mailService;
  }
}
const mailService = new MailService("APIKEY1234567890")
const emailSender = new EmailSender(mailService)

在範例化 EmailSender 類時將它的依賴項通過 constructor 建構函式引數的形式注入到類的內部,這種寫法就是依賴注入。

通過依賴注入降了程式碼之間的耦合度,增加了程式碼的可維護性。MailService 類中程式碼的更改再也不會影響 EmailSender 類。

2、DI 框架

Angular 有自己的 DI 框架,它將實現依賴注入的過程隱藏了,對於開發者來說只需使用很簡單的程式碼就可以使用複雜的依賴注入功能。

在 Angular 的 DI 框架中有四個核心概念:

  • Dependency:元件要依賴的範例物件,服務範例物件

  • Token:獲取服務範例物件的標識

  • Injector:注入器,負責建立維護服務類的範例物件並向元件中注入服務範例物件(管理服務物件的建立和獲取)。

  • Provider:設定注入器的物件,指定建立服務範例物件的服務類和獲取範例物件的標識。(Provider:提供程式)

2.1 注入器 Injectors

注入器負責建立服務類範例物件,並將服務類範例物件注入到需要的元件中。

  • 建立注入器

    import { ReflectiveInjector } from "@angular/core"
    // 服務類
    class MailService {}
    // 建立注入器並傳入服務類
    const injector = ReflectiveInjector.resolveAndCreate([MailService])
  • 獲取注入器中的服務類範例物件

    const mailService = injector.get(MailService)
  • 服務範例物件為單例模式,注入器在建立服務範例後會對其進行快取

    const mailService1 = injector.get(MailService)
    const mailService2 = injector.get(MailService)
    
    console.log(mailService1 === mailService2) // true
  • 不同的注入器返回不同的服務範例物件

    const injector = ReflectiveInjector.resolveAndCreate([MailService])
    const childInjector = injector.resolveAndCreateChild([MailService])
    
    const mailService1 = injector.get(MailService)
    const mailService2 = childInjector.get(MailService)
    
    console.log(mailService1 === mailService2) // false
  • 服務範例的查詢類似函數作用域鏈,當前級別可以找到就使用當前級別,當前級別找不到去父級中查詢

    const injector = ReflectiveInjector.resolveAndCreate([MailService])
    const childInjector = injector.resolveAndCreateChild([])
    
    const mailService1 = injector.get(MailService)
    const mailService2 = childInjector.get(MailService)
    
    console.log(mailService1 === mailService2) // true

2.2 提供者 Provider

  • 設定注入器的物件,指定了建立範例物件的服務類和存取服務範例物件的標識。

    const injector = ReflectiveInjector.resolveAndCreate([
      { provide: MailService, useClass: MailService }
    ])
  • 存取依賴物件的標識也可以是字串型別

    const injector = ReflectiveInjector.resolveAndCreate([
      { provide: "mail", useClass: MailService }
    ])
    const mailService = injector.get("mail")
  • useValue

    const injector = ReflectiveInjector.resolveAndCreate([
      {
        provide: "Config",
        useValue: Object.freeze({
          APIKEY: "API1234567890",
          APISCRET: "500-400-300"
        })
      }
    ])
    const Config = injector.get("Config")

將範例物件和外部的參照建立了鬆耦合關係,外部通過標識獲取範例物件,只要標識保持不變,內部程式碼怎麼變都不會影響到外部。

更多程式設計相關知識,請存取:!!

以上就是angular學習之聊聊依賴注入的詳細內容,更多請關注TW511.COM其它相關文章!