멀티 모듈을 사용하는 앱에서 Dagger 적용하기

애플리케이션 개발시 다음과 같은 특수한 목적으로 가지고 멀티 모듈을 사용한 개발 방법을 택할 수 있다.

  • 대규모 프로젝트에서의 개발자간 협업
  • 빌드 시간 단축
  • 모듈의 재사용
  • 여러가지 버전의 앱을 만들 때
  • APK 용량을 줄일 때 ( Dynamic Feature Module)

안드로이드 프로젝트에서 멀티 모듈의 종류는 일반적인 모듈과 다이나믹 피쳐 모듈 두가지가 있다. 어떤 모듈을 사용하느냐에 따라 Dagger를 사용한 의존성 주입 설계 방법이 달라진다.

멀티 모듈을 사용하는 프로젝트

일반적인 모듈을 사용하는 프로젝트에서는 하위 모듈은 애플리케이션을 모듈을 참조할 수 없다. 그렇기 때문에 모듈간의 의존성 방향은 애플리케이션 모듈이 하위 모듈을 참조하는 형태이고, 하위 모듈의 Dagger 컴포넌트는 애플리케이션 모듈의 컴포넌트를 의존하는 형태가 된다. 다음 그림을 참조하자.

 

[그림 1] 멀티 모듈 프로젝트에서 대거 그래프의 예시

멀티 모듈 프로젝트에서 같은 레벨에 있는 모듈들이 서로 의존해서는 안된다. 이 경우 순환참조가 이루어 지기  때문에 여러가지 문제들이 발생한다.

[그림2] 순환 참조 예시

만약 모듈간의 참조가 필요한 경우는 공통으로 참조하는 클래스를 상위 모듈로 옮길 수 있다.

다이나믹 피쳐 모듈을 사용하는 프로젝트

다이나믹 피쳐 모듈을 사용하면 일반적으로 모듈간의 의존 방향이 반전된다. 하위 모듈이 애플리케이션 모듈을 의존하며, 애플리케이션은 하위 모듈을 의존할 수 없다. 그렇기 때문에 Dagger를 사용한 의존성 주입시 dagger.android 패키지를 이용한 그래프를 구성하는 것이 불가능하다. Dagger는 하위 컴포넌트를 참조할 수 있어야 컴파일 타임에 그래프를 구성할 수 있기 때문이다.

[그림3]다이나믹 멀티 모듈을 사용하는 프로젝트에서 대거 그래프의 예시

Dagger에서는 이 문제를 해결하는데 사용할 수 있는 Component dependency라는 메커니즘을 제공하고 있다.  일반적인 모듈을 사용하는 프로젝트와는 다르게 다이나믹 피쳐모듈의 컴포넌트가 애플리케이션의 컴포넌트를 의존하는 형태로 그래프를 만들 수 있다. 

다이나믹 피쳐 모듈 프로젝트에 Dagger 적용하기

기기의 사진들을 그리드 목록으로 보여주는 간단한 다이나믹 피쳐 모듈 프로젝트 예제를 살펴보자. 다음과 같은 모듈들로 구성된다.

  • app 모듈 : 애플리케이션 모듈로, Base APK가 된다.
  • photo 모듈 : 사진 목록을 보여주는 PhotoActivity를 포함한 동적 모듈
  • core 모듈 : 모든 모듈들이 공통적으로 참조하는 클래스를 포함하는 모듈

Dagger 컴포넌트 코드를 살펴보면, 하위 컴포넌트(PhotoComponent)가 상위 컴포넌트(CoreComponent)를 의존하기 위해 @Component의 dependencies 애트리뷰트를 사용한다.

core/CoreComponent.kt

@Singleton
@Component(modules = [CoreModule::class])
interface CoreComponent{

    fun getApplication():Application // 하위 컴포넌트가 참조할 수 있도록 노출

    @Component.Factory
    interface Factory{
        fun create(@BindsInstance application: Application):CoreComponent
    }

}

photo/PhotoComponent.kt

@ActivityScope
@Component(modules = [PhotoModule::class], dependencies =[CoreComponent::class] )
interface PhotoComponent{//CoreComponent에 의존한다.

    fun inject(photoActivity: PhotoActivity)

    @Component.Factory
    interface Factory {
        fun create(coreComponent: CoreComponent,
                   photoModule: PhotoModule,
                   @BindsInstance photoActivity:PhotoActivity): PhotoComponent
    }
}

위 예제는 github에서 다운로드 가능하다.

TL; DR

다이나믹 피쳐 모듈을 사용하면 조직이나 다른 팀간의 병합충돌 없이 작업하고 코드의 재사용 및 캡슐화를 촉진할 수 있다. 또한 빌드 시간이 향상되며, 필요한 기능만을 사용자에게 전달하여 APK 사이즈를 축소 할 수 있다. 

다이나믹 피쳐 모듈은 의존성 방향이 역전되기 때문에, android.dagger 패키지를 사용하는데 어려움이 있다. 이를 해결하기 위해 직접 Component Dependency 메커니즘을 활용하고 컴포넌트간의 의존성을 직접 설정하자.

 

카테고리: Dagger2Kotlin

0개의 댓글

답글 남기기

Avatar placeholder

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.