初心者の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



クラスを検討してDaggerBattleComponent



DaggerBattleComponent



カーソルを置き、Ctrl + B(またはCtrl + LMB、Command + LMB)を押します。 以下が表示されます。



 @Generated( value = "dagger.internal.codegen.ComponentProcessor", comments = "https://google.github.io/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()



ば幸いです。 次に、 Starks



Boltons



依存関係をさらに追加します。 インターフェイスにメソッドを追加します。



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





変更を行った後、プロジェクトを再構築します。 ここで、 DaggerBattleComponent



クラスを確認してDaggerBattleComponent



。 すべてを正しく実行すると、次のように表示されます。



 @Generated( value = "dagger.internal.codegen.ComponentProcessor", comments = "https://google.github.io/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



ます。 彼は、 Cash



Soldiers



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)を押します。 Cash



Soldiers



依存関係を提供するために、クラスにBraavosModule



モジュールBraavosModule



含まれていることがBraavosModule



ます。



まとめ



Dagger 2によって生成されたクラスを分析し、Dagger 2がbuilder



パターンを使用して依存関係を提供していることに気付きました。 また、 @Provides



@Module



および@Provides



を使用する簡単な例を見てみました。



次は?



次の記事では、Dagger 2を使用したAndroidアプリケーションの例を見ていきます。

次の記事は12月29日以降にリリースされます。 しばらくお待ちください。



All Articles