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


135

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

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

답변:


228

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

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


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

  • 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);
    }
}

4
Component B에 모듈 B를 추가하지 않는 하위 구성 요소 설정이 있는데, 이는 componentA 빌더에 moduleB가 필요하지 않음을 의미합니다. 이것은 내가 응용 프로그램 시작에 ComponentA의 생성을 가능하게 예상하는 일을 할 수있는 다음 인스턴스 m
FriendlyMikhail

2
@MikeN-ComponentA에서 ModuleB를 제거하는 방법을 강조 할 수 있습니까? ComponentA와 ComponentB에 다른 범위를 제공하는 경우에만 ComponentA에서 ModuleB를 제거 할 수 있습니다.
Praveer Gupta

1
다른 범위에 있기 때문에 설정이 올바르게 작동합니다. 사과.
FriendlyMikhail

2
" SomeClassB1에 따라 달라집니다 SomeClassA1. ComponentA명시 적 종속성을 정의 할 수 있습니다." ==> " ComponentB명시 적으로 종속성을 정의 해야합니다"를 의미 했습니까?
Tar

1
@Tar가 지적한 것과 유사하게, 나는 " SomeClassB1에 의존한다 SomeClassA1. 의존성을 ComponentA명시 적으로 정의 할 필요는 없다 " 는 것을 이해한다 . " ComponentB명시 적으로 종속성을 정의 할 필요는 없습니다 "라는 의미 입니다.
Sebas LG

45

설명서 에 따르면 :

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는 전체 그래프에 액세스 할 수 있기 때문에 지금 당장.


2
올바르게 이해하면라는 인터페이스가 없습니다 @Submodule. 오타입니까?
이슬람 살라

나는 이것이 실제 사례를 사용하여 차이점을 보여주는 방법을 좋아합니다. 그러나 이것은 문서를 읽는 것보다 더 혼란 스럽습니다. classes정확한 요점을 설명하기 위해 적은 수의 예제와 더 많은 그림 을 갖는 것이 도움이 될 것 입니다.
sudocoder

18

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

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

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

하위 구성 요소 :

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

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

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

출처 : 링크


하위 구성 요소가 AppComponent를 묶은 경우 다이어그램이 더 의미가 없습니까?
Florian Walther

1

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

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

1
아마도 두 번째 경우에는 '@Component'에 부모가있을 수 있다고 말하는 것이 올바르지 않습니다. 오히려 '@Component'에는 부모가 없지만 다른 것들은 구성 요소 종속성을 통해 그에 의존 할 수 있습니다 (간단히 사용).
demaksee

@demaksee 모르겠다. 구성 요소 계층 구조를 매핑하면 DAG를 얻을 수 있으며이 관계를 그래프 컨텍스트에서 부모 자식으로 참조하는 표준 방법이라고 생각합니다. 우리가 단검의 내부 활동에 대해 이야기하고 있다면 그것이 올바른 단어가 아닐 수도 있습니다.
arekolek
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.