[dagger] 단검 2 하위 구성 요소 및 구성 요소 종속성

Dagger 1의 plus()방법은 이전 응용 프로그램에서 매우 자주 사용 된 방법이므로 부모 그래프 바인딩에 대한 전체 액세스 권한을 가진 하위 구성 요소를 원할 수도 있습니다.

어떤 상황 에서 하위 구성 요소 종속성 대신 구성 요소 종속성 을 사용하는 것이 좋으며 그 이유는 무엇입니까?



답변

구성 요소 종속성-두 구성 요소를 독립적으로 유지하려는 경우에 사용하십시오.

하위 구성 요소-두 구성 요소를 결합시키려는 경우에 사용하십시오.


아래 예제를 사용하여 구성 요소 종속성하위 구성 요소 를 설명 합니다. 예제에 주목할만한 몇 가지 사항은 다음과 같습니다.

  • SomeClassA1의존없이 만들 수 있습니다. 방법 ModuleASomeClassA1통해 제공 및 인스턴스 provideSomeClassA1().
  • SomeClassB1없이는 만들 수 없습니다 SomeClassA1. ModuleB의 인스턴스 가 메소드에 인수로 전달 된 SomeClassB1경우에만 인스턴스를 제공 할 수 있습니다 .SomeClassA1provideSomeClassB1()
@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;
    }
}

단검은 컴포넌트 / 하위 컴포넌트 선언 이 초기화 될 때마다 메소드 SomeClassA1의 인수로 인스턴스를 전달하는 것을 provideSomeClassB1()처리합니다 . 의존성을 충족시키는 방법을 Dagger에게 지시해야합니다. 이는 Component dependency 또는 Subcomponent를 사용하여 수행 할 수 있습니다 .ModuleBModuleB

구성 요소 종속성

아래의 컴포넌트 종속성 예제에서 다음 사항을 참고하십시오.

  • ComponentB주석 의 dependencies메소드를 통해 종속성을 정의해야합니다 @Component.
  • ComponentA선언 할 필요가 없습니다 ModuleB. 이렇게하면 두 구성 요소가 독립적으로 유지됩니다.
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(). 이렇게하면 두 구성 요소가 결합됩니다. 실제로는를 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당신에게에 액세스 할 수 있습니다 전체 가 모든 개체에 대한 액세스는 선언이, 예를 선언 할 때 부모로부터 바인딩 그래프 Module의.

하자의 말, 당신이 ApplicationComponent모두 포함하는 Android관련 물건을 ( LocationService, Resources, SharedPreference, 등). 또한 API를 다루기 DataComponent위해 지속성을 위해 사물을 관리하는 곳을 원합니다 WebService. 당신이 부족있는 유일한 방법은 DataComponent이다 Application Context에있는 상주 ApplicationComponent. 를 얻을 수있는 간단한 방법 Context에서은 DataComponent에 종속 될 것이다 ApplicationComponent. 신고 된 물건에만 액세스 할 수 있으므로 Context명시 적으로 신고 ApplicationComponent해야합니다. 이 경우 수동 작업이 없으므로 Submodules부모 로 지정하지 않고 Component하위 모듈을 부모 모듈에 명시 적으로 추가 할 필요가 없습니다 .

MySubcomponent mySubcomponent = myComponent.plus(new ChildGraphModule("child!")); // No need!

이제 주입 할 경우 고려 WebService에서 DataComponentLocationService에서 ApplicationComponent당신에 Fragment사용하는 바인딩 @Submodule plus위의 기능을. 여기에 시원한 것은 당신이 (바인딩하고 구성 요소가 있다는 것입니다 ApplicationComponent) 않습니다 하지 노출 할 필요 WebServiceLocationService는 전체 그래프에 액세스 할 수 있기 때문에 지금 당장.


답변

다음은 Component 및 SubComponent에 대한 이해를 돕기위한 스크린 샷이있는 코드 예제입니다.

구성 요소:
여기에 이미지 설명을 입력하십시오

  1. AppComponent에는 두 가지 선언이 있습니다.
  2. AppComponent는 App 클래스로 초기화됩니다.
  3. HomeActivityComponent는 AppComponent에 따라 다릅니다.
  4. DaggerHomeActivityComponent 초기화에 대한 HomeActivity에서 AppComponent 객체를 컴포지션으로 제공합니다.

하위 구성 요소 :

여기에 이미지 설명을 입력하십시오

  1. AppComponent에는 하위 구성 요소가 포함됩니다.
  2. AppComponent는 App 클래스로 초기화됩니다.
  3. SubComponent는 그의 ParentComponent에 대해 모른다. 그것은 모듈을 포함하여 자신의 의존성을 제공합니다.
  4. HomeActivity에서 부모 구성 요소를 사용하여 하위 구성 요소를 주입하고 있습니다.

그리고 그림 도표 :
여기에 이미지 설명을 입력하십시오

출처 : 링크


답변

지금까지 내가 알지 못했던 또 하나의 사실은 다음과 같습니다.

  • @Subcomponent(다른 구성 요소가 같은 인스턴스를 수 있지만 인스턴스는 정확히 하나 개의 부모 구성 요소가 @Subcomponent해당 인스턴스의 부모)
  • A @Component컴포넌트 의존성을 통해 선언 된 0 개, 1 개 또는 많은 “부모”컴포넌트를 가질 수 있습니다.

답변