天天看點

Dagger——Android的依賴注入架構

Dagger-快速依賴注入器

這個架構它的好處是它沒有采用反射技術(Spring是用反射的),而是用預編譯技術,因為基于反射的DI非常地耗用資源(空間,時間)。這裡記錄一下上面文章的一些關鍵的要點

聲明依賴關系

Dagger 構造應用程式的類對象,并組合其依賴關系。 Dagger使用 

javax.inject.Inject

 annotation 标記那些需要依賴注入的構造函數和成員變量。

Dagger将使用 

@Inject 注釋的構造函數

 建立類對象。 當請求建構新的類對象時, Dagger 将自動擷取相應的參數, 并調用構造函數。

class Thermosiphon implements Pump {
  private final Heater heater;

  @Inject
  Thermosiphon(Heater heater) {
    this.heater = heater;
  }
  ...
}
           
class CoffeeMaker {
  @Inject Heater heater;
  @Inject Pump pump;

  ...
}
           

Dagger 可以直接注入成員變量。在這個例子中, 它擷取Heater對象, 并注入到成員變量heater, ,擷取Pump對象并注入到成員變量pump。

注意,當類中含有@Inject注釋的成員變量, 卻沒有@Inject注釋的構造函數時, Dagger将使用類的預設構造函數。若類中缺少@Inject注釋, 該類是不能由Dagger建立的。這這個例子中,因為Thermosiphon類中有@Inject注釋的構造函數,當有數要建構這個類對象的時候,就使用這個@Inject注釋的構造函數來建構類的對象。

Dagger不支援函數注入。

實作依賴關系

  預設情況下, Dagger 通過構造相應類型的對象來實作依賴關系。當請求一個CoffeMaker對象時, Dagger将調用new CoffeeMaker()構造函數, 并指派給@Inject标記的成員變量。

但是@Inject并不是在任何情況下都可以:

  • 接口類型不能被構造
  • 第三方的類不能被注釋構造。
  • 可配置的對象必須被配置好

對那些使用@Inject效率極低的情況, 可以使用@Provides注釋函數來實作依賴關系。這些函數的傳回類型定義其實作的依賴關系。

例如, 當需要一個Heater時, Dagger将調用provideHeater()函數擷取。

@Provides Heater provideHeater() {
  return new ElectricHeater();
}
           

@Provides注釋的函數也可以有他們自己的依賴關系。下面這個Provides函數依賴于一個Thermosiphon對象:

@Provides Pump providePump(Thermosiphon pump) {
  return pump;
}
           

所有的@Provides函數必須屬于一個Module。這些Module類使用@Module注釋。

@Module
class DripCoffeeModule {
  @Provides Heater provideHeater() {
    return new ElectricHeater();
  }

  @Provides Pump providePump(Thermosiphon pump) {
    return pump;
  }
}
           

注意,通常情況下, 約定@Provides函數以provide作為字首, @Module類以Module作為字尾。

建構ObjectGraph(對象圖表)

@Inject 和 @Provides 注釋的類建構了一個對象圖表。這些對象與對象之間通過依賴關系互相關聯。通過函數

ObjectGraph.create()

擷取這個對象圖表, 這個函數可以接受一個或多個Module作為參數:

ObjectGraph objectGraph = ObjectGraph.create(new DripCoffeeModule());