Dagger 1のplus()
メソッドは、以前のアプリケーションで非常に頻繁に使用したものであるため、親グラフバインディングにフルアクセスできるサブコンポーネントが必要な場合があることを理解しています。
サブコンポーネントの依存関係の代わりにコンポーネントの依存関係を使用することがどのような状況で有益ですか?
コンポーネントの依存関係-2つのコンポーネントを独立させたい場合に使用します。
サブコンポーネント-2つのコンポーネントを結合したい場合に使用します。
以下の例を使用して、コンポーネントの依存関係およびサブコンポーネントを説明します。この例について注意する価値があるいくつかのポイントは次のとおりです。
SomeClassA1
は、依存関係なしで作成できます。 ModuleA
は、provideSomeClassA1()
メソッドを介してSomeClassA1
のインスタンスとインスタンスを提供します。SomeClassB1
は、SomeClassA1
なしでは作成できません。 ModuleB
は、SomeClassB1
のインスタンスがprovideSomeClassB1()
メソッドの引数として渡される場合にのみ、SomeClassA1
のインスタンスを提供できます。@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は、ModuleB
を宣言するコンポーネント/サブコンポーネントが初期化されるたびに、ModuleB
のprovideSomeClassB1()
メソッドへの引数としてSomeClassA1
のインスタンスを渡します。依存関係を満たす方法をDaggerに指示する必要があります。これは、コンポーネント依存関係またはサブコンポーネントを使用して実行できます。
以下のコンポーネント依存関係の例では、次の点に注意してください。
ComponentB
は、@Component
アノテーションのdependencies
メソッドを介して依存関係を定義する必要があります。ComponentA
は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
注釈があります。ComponentA
は、インターフェイスメソッドcomponentB()
を介してModuleB
を宣言しました。これにより、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
を使用すると、コンポーネントの依存関係を通じてプロビジョニングメソッドとして公開されたバインディングのみにアクセスできます。つまり、親Component
で宣言されている型のみにアクセスできます。
SubComponent
は、宣言時に親からentireバインディンググラフへのアクセスを提供します。つまり、Module
sで宣言されたすべてのオブジェクトにアクセスできます。
たとえば、ApplicationComponent
に関連するすべてのもの(Android
、LocationService
、Resources
など)を含むSharedPreference
があるとします。また、DataComponent
と共に永続化のために物事を管理するWebService
を持ち、APIを処理します。 DataComponent
に欠けているのは、ApplicationComponent
にあるApplication Context
だけです。 Context
からDataComponent
を取得する最も簡単な方法は、ApplicationComponent
に依存することです。 Context
で明示的に宣言されているApplicationComponent
があることを確認する必要があります。これは、宣言されたものにしかアクセスできないためです。この場合、手作業はありません。つまり、親Submodules
でComponent
を指定し、サブモジュールを次のように親モジュールに明示的に追加する必要はありません。
MySubcomponent mySubcomponent = myComponent.plus(new ChildGraphModule("child!")); // No need!
ここで、上記の@Submodule
WebService
機能を使用してバインドするDataComponent
からLocationService
およびApplicationComponent
からFragment
をplus
に挿入する場合を考えてみましょう。ここでクールなのは、(ApplicationComponent
)にバインドしているコンポーネントはnotがWebService
またはLocationService
を公開する必要があることです。これは、グラフ全体にアクセスできるためです。直ちに。
コンポーネントとサブコンポーネントをさらに理解するためのスクリーンショット付きのコード例を次に示します。
サブコンポーネント:
ソース: link
今まで気づかなかったもう1つのことは、次のとおりです。
@Subcomponent
インスタンスには、親コンポーネントが1つだけあります(ただし、異なるコンポーネントが同じ@Subcomponent
をインスタンス化し、そのインスタンスの親になることができます)@Component
には、 コンポーネントの依存関係 で宣言された0、1、または多くの親コンポーネントがあります