본문 바로가기

안드로이드

[Android] 5. 구글 코드랩 Dagger를 이용한 리팩토링 - Main Flow

개요

해당 게시글은 구글 코드랩을 번역한 게시글입니다.

 

Main Flow에 대거를 적용하기

이전과 마찬가지로 MainActivity가 Dagger를 사용하여 의존성을 관리하기를 원한다. 이 경우에는 MainViewModel, UserManager가 관리 대상이다.

 

대거에게 MainActivity가 의존성 주입을 받는 대상이라고 알려야 한다. AppComponet에 MainActivity를 매개 변수로 사용하여 메소드를 추가한다.

 

AppComponent.kt

@Component(modules = [StorageModule::class])
interface AppComponent {
    ...

    // 컴포넌트에 의해 의존성을 주입 받는 클래스
    fun inject(activity: RegistrationActivity)
    fun inject(activity: MainActivity)
}

메소드의 이름은 중요치 않다. 중요한건 매개변수이다. 

 

MainActivity에서 대거에서 주입할 항목을 정의하고 그래프를 주입해본다.

 

1. 먼저 UserManager를 onCreate의 지역 변수 대신 @Inject를 통해 주입받는다. MainViewModel도 그렇게 처리한다.

class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var userManager: UserManager

    @Inject
    lateinit var mainViewModel: MainViewModel

    ...
}

 

2. userManager와 mainViewModel의 초기화 코드를 제거한다. 이는 대거가 수행하게 된다.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        ...

        // 아래 라인을 제거하세요
        userManager = (application as MyApplication).userManager
        if (!userManager.isUserLoggedIn()) {
           ...
        } else {
           ...
           // 아래 라인 역시 제거하세요
            mainViewModel = MainViewModel(userManager.userDataRepository!!)
           ...
        }
    }
    ...
}

 

3. MainActivity에서 appComponent의 inject 메소드를 수행하여 주입될 필드를 생성한다.

class MainActivity : AppCompatActivity() {
    ...
    override fun onCreate(savedInstanceState: Bundle?) {

        (application as MyApplication).appComponent.inject(this)

        super.onCreate(savedInstanceState)
        ...
    }
}

참고로 UserManager는 이미 그래프에 존재하고, 제공할 방법을 안다. 하지만, MainViewModel의 경우 그렇지 않기 때문에 @Inject로 처리해준다.

 

MainViewModel.kt

class MainViewModel @Inject constructor(private val userDataRepository: UserDataRepository) { ... }

MainViewModel은 UserDataRepository에 의존하기 때문에 UserDataRepository에도 @Inject 처리해준다. 

 

UserDataRepository.kt

class UserDataRepository @Inject constructor(private val userManager: UserManager) { ... }

UserManager는 이미 대거 그래프에 존재하기 때문에 따로 처리할 필요가 없다.

 

현재 그래프의 상태

이제 빌드를 수행하면 앱이 정상적으로 동작할 것이다. 다시 실행하면 이전에 사용자 등록 절차를 거쳤으므로 로그인 화면이 표시된다. 처음으로 앱을 실행했을 때 처럼 시작하며련 'Unregister' 버튼을 클릭하여 등록 절차로 이동할 수 있다.

 

이제 다시 등록을 진행하면, 또 메인 페이지로 이동하지 않는다. 역시 로그인 페이지로 이동한다. 해당 버그가 다시 반복해서 발생했다. 그 이유는 Main과 Registration 모두 UserManager가 Application Graph에서 주입되기 때문이다.

 

다시 말하면 대거는 현재 새로 의존성을 주입해줄 때 객체를 계속 새로이 생성하고 있다. Dagger가 같은 인스턴스를 재사용하도록 하기 위해서는 Scoping(범위 지정)을 해주어야 한다.