初心者のAndroid開発者向けの短剣2。 ダガー2.パート2

この記事は、著者によると、 依存関係Dagger 2フレームワークの実装を理解できない、またはそれをやろうとしている人向けの一連の記事の第5部です。 オリジナルは2017年12月17日に書かれました。 無料翻訳。

画像

これは、 初心者のAndroid開発者向けのDagger 2シリーズの5番目の記事です。 前のものを読んでいない場合、 ここにいます。

一連の記事



一連の記事の前半


前回の記事で、依存性注入(DI)の手動使用が作業を複雑にし、定型コードの量を増やす方法について説明しました。 Dagger 2がこの痛みをどのように軽減し、定型コードを生成するかを調べた後。 また、Dagger 2のアノテーションプロセッサと基本的なアノテーションについても説明しました。次に、例を使用してこれらのアノテーションを適用し、Dagger 2を使用して依存関係を実装しました。

解剖学DaggerBattleComponent


Dagger 2をよりよく理解するには、 DaggerBattleComponentクラスを検討してDaggerBattleComponentDaggerBattleComponentカーソルを置き、Ctrl + B(またはCtrl + LMB、Command + LMB)を押します。 以下が表示されます。

 @Generated( value = "dagger.internal.codegen.ComponentProcessor", comments = "https://google.imtqy.com/dagger" ) public final class DaggerBattleComponent implements BattleComponent { private DaggerBattleComponent(Builder builder) {} public static Builder builder() { return new Builder(); } public static BattleComponent create() { return new Builder().build(); } //    @Override public War getWar() { return new War(new Starks(), new Boltons()); } public static final class Builder { private Builder() {} public BattleComponent build() { return new DaggerBattleComponent(this); } } } 

これは、Dagger 2がハード依存関係の問題を解決するために生成するものです。 クラスが実装するインターフェースを見ると、これがBattleComponentあることがBattleComponentます。これは以前に作成し、 Warクラスのインスタンスを提供するgetWar()メソッドを記述したインターフェースです。

この依存関係は、 builderパターンを使用して提供されます。 このテンプレートの詳細については、 こちらこちらをご覧ください

新しいことを学びましょう


getWar()メソッドが必要な理由を明確に理解してgetWar()ば幸いです。 次に、 StarksBoltons依存関係をさらに追加します。 インターフェイスにメソッドを追加します。

 @Component interface BattleComponent { War getWar(); //   Starks getStarks(); Boltons getBoltons(); } 

変更を行った後、プロジェクトを再構築します。 ここで、 DaggerBattleComponentクラスを確認してDaggerBattleComponent 。 すべてを正しく実行すると、次のように表示されます。

 @Generated( value = "dagger.internal.codegen.ComponentProcessor", comments = "https://google.imtqy.com/dagger" ) public final class DaggerBattleComponent implements BattleComponent { private DaggerBattleComponent(Builder builder) {} public static Builder builder() { return new Builder(); } public static BattleComponent create() { return new Builder().build(); } @Override public War getWar() { return new War(getStarks(), getBoltons()); } @Override public Starks getStarks() { return new Starks(); } @Override public Boltons getBoltons() { return new Boltons(); } public static final class Builder { private Builder() {} public BattleComponent build() { return new DaggerBattleComponent(this); } } } 

ご覧のとおり、Dagger 2はgetStarks()およびgetBoltons()メソッドを実装しgetStarks()

Dagger 2に、 Boltonsクラスの@Injectアノテーションを使用してこれらの依存関係を取得するように指示しました。 何かを壊しましょう。 Boltonsクラスから@Injectアノテーションを削除します。 プロジェクトを再構築します。

何も起きなかった? はい、エラーは表示されませんでしたが、プロジェクトを開始してみてください。 次のエラーが表示されるはずです。

画像

エラーテキストを読むと、 getWar()または@Providesがない場合、 getWar()およびgetBoltons()メソッドが機能しないことが明確に示されます。

前述のように、Dagger 2ではエラーを簡単に追跡できます。 このクラスで少し遊ぶことができます。

@Moduleおよび@Provides


深く掘り下げて、いくつかの便利なアノテーション- @Module@Providesを扱いましょう。 プロジェクトのサイズが大きくなった場合に使用する必要があります。

@Module


要するに、この注釈はモジュールとクラスをマークします。 Androidについて話す。 ContextModuleモジュールを持つことができ、このモジュールは他のクラスのApplicationContextおよびContext依存関係を提供しApplicationContext 。 これを行うには、 @ModuleアノテーションでContextModuleクラスをマークする必要があります。

@Provides


つまり、モジュール内で依存関係を提供するメソッドをマークするには、この注釈が必要です。 前述の例では、 ContextModuleクラスに@Moduleアノテーションを付けましたが、 ApplicationContextおよびContext依存関係を提供するメソッドに@Moduleアノテーションを付ける必要もあります。

小さな例を見てください( ブランチへのリンク )。


Braavosが提供する2つのサービス-お金(現金)と兵士(兵士)(これらのサービスを提供するかどうかはわかりませんが、これは一例です) 2つのクラスを作成しましょう。

 public class Cash { public Cash(){ // -  } } 

 public class Soldiers { public Soldiers(){ // -  } } 

ここでモジュールを作成し、 BraavosModuleという名前をBraavosModuleます。 彼は、 CashSoldiers 2つの依存関係を提供します。

 @Module //  public class BraavosModule { Cash cash; Soldiers soldiers; public BraavosModule(Cash cash, Soldiers soldiers){ this.cash=cash; this.soldiers=soldiers; } @Provides //   Cash Cash provideCash(){ return cash; } @Provides //   Soldiers Soldiers provideSoldiers(){ return soldiers; } } 

前に見たように、すべてのモジュールを@Moduleアノテーションでマークし、依存関係を提供するメソッドを@Moduleアノテーションでマークする必要があります。

BattleOfBastardsクラスに戻り、 provideCash()およびprovideSoldiers()メソッドを実装するBattleOfBastardsコンポーネントにBattleOfBastardsましょう。

 @Component(modules = BraavosModule.class) interface BattleComponent { War getWar(); Cash getCash(); Soldiers getSoldiers(); } 

 public class BattleOfBastards { public static void main(String[] args){ Cash cash = new Cash(); Soldiers soldiers = new Soldiers(); BattleComponent component = DaggerBattleComponent .builder() .braavosModule(new BraavosModule(cash, soldiers)) .build(); War war = component.getWar(); war.prepare(); war.report(); //     component.getCash(); component.getSoldiers(); } } 

モジュールが@Componentアノテーション@Component追加されていることに注意してください。 これは、コンポーネントに特定のモジュールが含まれることを示します。

@Component(modules = BraavosModule.class)

すべての変更後、プロジェクトを再構築します。 .create()クラスの.create()メソッドにエラーが表示されます。 モジュールを追加するときに、この依存関係をDagger 2に転送する必要があるという事実のために発生しました。次のようになります。

BattleComponent component = DaggerBattleComponent.builder().braavosModule(new BraavosModule(cash, soldiers)).build();

すべてのモジュールを含めたら、 Componentを使用してそれらのメソッドの使用を開始できComponent

component.getCash(); component.getSoldiers();

確認したい場合は、 DaggerBattleComponentてCtrl + B(またはCtrl + LMB、Command + LMB)を押します。 CashSoldiers依存関係を提供するために、クラスにBraavosModuleモジュールBraavosModule含まれていることがBraavosModuleます。

まとめ


Dagger 2によって生成されたクラスを分析し、Dagger 2がbuilderパターンを使用して依存関係を提供していることに気付きました。 また、 @Provides @Moduleおよび@Providesを使用する簡単な例を見てみました。

次は?


次の記事では、Dagger 2を使用したAndroidアプリケーションの例を見ていきます。
次の記事は12月29日以降にリリースされます。 しばらくお待ちください。

Source: https://habr.com/ru/post/J344886/


All Articles