Dagger 1 のplus()メソッドは、以前のアプリケーションで頻繁に使用したものなので、親グラフ バインディングへの完全なアクセス権を持つサブコンポーネントが必要になる状況は理解できます。
サブコンポーネントの依存関係の代わりにコンポーネントの依存関係を使用すると、どのような状況で有益でしょうか?またその理由は?
コンポーネントの依存関係 - 2 つのコンポーネントを独立させたい場合に使用します。
サブコンポーネント - 2 つのコンポーネントを結合したままにしたい場合に使用します。
以下の例を使用して、コンポーネントの依存関係とサブコンポーネントについて説明します。この例で注目すべき点は次のとおりです。
SomeClassA1依存せずに作成できます。メソッドを介してのModuleAインスタンスを提供します。SomeClassA1provideSomeClassA1()SomeClassB1なしでは作成できませんSomeClassA1。のインスタンスが引数としてメソッドに渡された場合にのみModuleB、 のインスタンスを提供できます。SomeClassB1SomeClassA1provideSomeClassB1()@Module
public class ModuleA {
@Provides
public SomeClassA1 provideSomeClassA1() {
return new SomeClassA1();
}
}
@Module
public class ModuleB {
@Provides
public SomeClassB1 provideSomeClassB1(SomeClassA1 someClassA1) {
return new SomeClassB1(someClassA1);
}
}
public class SomeClassA1 {
public SomeClassA1() {}
}
public class SomeClassB1 {
private SomeClassA1 someClassA1;
public SomeClassB1(SomeClassA1 someClassA1) {
this.someClassA1 = someClassA1;
}
}
Dagger は、コンポーネント/サブコンポーネントの宣言が初期化されるたびに、のインスタンスをSomeClassA1引数としてprovideSomeClassB1()メソッド onに渡します。依存関係を満たす方法を Dagger に指示する必要があります。これは、 Component の依存関係またはSubcomponentを使用して実行できます。ModuleBModuleB
以下のコンポーネントの依存関係の例では、次の点に注意してください。
ComponentBアノテーション のdependenciesメソッドを介して依存関係を定義する必要があります。@ComponentComponentA宣言する必要はありませんModuleB。これにより、2 つのコンポーネントの独立性が保たれます。public class ComponentDependency {
@Component(modules = ModuleA.class)
public interface ComponentA {
SomeClassA1 someClassA1();
}
@Component(modules = ModuleB.class, dependencies = ComponentA.class)
public interface ComponentB {
SomeClassB1 someClassB1();
}
public static void main(String[] args) {
ModuleA moduleA = new ModuleA();
ComponentA componentA = DaggerComponentDependency_ComponentA.builder()
.moduleA(moduleA)
.build();
ModuleB moduleB = new ModuleB();
ComponentB componentB = DaggerComponentDependency_ComponentB.builder()
.moduleB(moduleB)
.componentA(componentA)
.build();
}
}
SubComponent の例では、次の点に注意してください。
ComponentBへの依存関係が定義されていないため、独立ModuleAして存在することはできません。を提供するコンポーネントに依存するようになりますModuleA。したがって、@Subcomponent注釈があります。ComponentAModuleBはインターフェイス メソッドを介して宣言されていますcomponentB()。これにより、2 つのコンポーネントが結合されます。実際、ComponentB経由でのみ初期化できますComponentA。public class SubComponent {
@Component(modules = ModuleA.class)
public interface ComponentA {
ComponentB componentB(ModuleB moduleB);
}
@Subcomponent(modules = ModuleB.class)
public interface ComponentB {
SomeClassB1 someClassB1();
}
public static void main(String[] args) {
ModuleA moduleA = new ModuleA();
ComponentA componentA = DaggerSubComponent_ComponentA.builder()
.moduleA(moduleA)
.build();
ModuleB moduleB = new ModuleB();
ComponentB componentB = componentA.componentB(moduleB);
}
}
ドキュメントによると:
Component Dependencyコンポーネントの依存関係を介してプロビジョニング メソッドとして公開されているバインディングのみにアクセスできます。つまり、parent で宣言されている型のみにアクセスできますComponent。
SubComponentバインディング グラフが宣言されると、その親からバインディング グラフ全体にアクセスできます。つまり、そのModulesで宣言されたすべてのオブジェクトにアクセスできます。
ApplicationComponent関連するすべてのAndroidもの ( LocationService、Resources、SharedPreferenceなど)を含むがあるとします。またDataComponent、永続性のために物事を管理する場所とWebService、API を処理する場所も必要です。あなたが欠けている唯一のものDataComponentはApplication Context、に存在するものですApplicationComponent。Contextfromを取得する最も簡単な方法はDataComponent、 への依存ApplicationComponentです。宣言されたものにしかアクセスできないため、Context明示的に宣言されていることを確認する必要があります。ApplicationComponentこの場合、手作業はありません。つまり、次のように親で指定して、サブモジュールを親モジュールに明示的に追加する必要はありませSubmodulesんComponent。
MySubcomponent mySubcomponent = myComponent.plus(new ChildGraphModule("child!")); // No need!
ここで、上記の機能を使用して、which バインドとの間でインジェクションWebServiceを行うケースを考えてみましょう。ここですばらしいのは、( )にバインドしているコンポーネントを公開する必要がなく、すぐにグラフ全体にアクセスできることです。DataComponentLocationServiceApplicationComponentFragment@Submodule plusApplicationComponentWebServiceLocationService