본문 바로가기
안드로이드

D.I (feat Hilt) 기본 2 - Scope

by 삽질러 2021. 11. 12.

 

D.I (feat Hilt) 기본 - 1

 

D.I (feat Hilt) 기본 - 1

Dependency Injection Dagger -> Hilt 구성요소 annotation @Inject @Component @Subcomponent @Module @Binds @Scope class RegistrationActivity : AppCompatActivity() { lateinit var registrationViewModel:..

pleaseonlydigonce.tistory.com

 

기본 -1 에서 기본적인 의존성 주입의 과정을 진행했다.

 

 

하지만 해당 과정을 통해서는 문제가 되는점이있는데 

 

Dagger를 통해 주입되는 항목이 전부 새로 생성되어서 주입된다는점이다. 

 

 

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

    // Classes that can be injected by this Component
    fun inject(activity: RegistrationActivity)
    fun inject(activity: MainActivity)
}

이전에 구성했던 AppComponent에 MainActivity도 추가하는 작업을 해보자. 

 

MainActivity는 아래와같은 의존성을 가지고있다. 

 

MainActivity -> UserManager -> Storage(SharedPreferencesStorage)

MainActivity -> mainViewModel -> UserDataRepository -> UserManager -> Storage(SharedPreferencesStorage)

 

이전에 이미 Dagger에게 UserManager클래스가 주입을 위해 사용되는것을 알려주었으므로 제외하고 

새롭게 주입될 클래스들을 이전과 같이 @Inject annotation을 추가해준다. 

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

 

class MainActivity : AppCompatActivity() {

    // @Inject annotated fields will be provided by Dagger
    @Inject
    /*private*/ lateinit var userManager: UserManager

    @Inject
    /*private*/ lateinit var mainViewModel: MainViewModel

    ...
}

Dagger 에 의해 주입되는 항목은 private로 사용할수 없기때문에 제거해준다 

 

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

        // Remove this line
        userManager = (application as MyApplication).userManager
        if (!userManager.isUserLoggedIn()) {
           ...
        } else {
           ...
           // Remove this line too
            mainViewModel = MainViewModel(userManager.userDataRepository!!)
           ...
        }
    }
    ...
}

 

기존의 초기화 코드를 삭제한후 실행하면 오류가 생긴다. 

 

초입에서 언급했던 것처럼 userManager을 여러군데에서 주입받으면서 생기는일인데 

 

Dagger를 사용하기전에는 Application클래스에서 생성된 동일한 UserManager를 

 

RegistrationActivity와 MainActivity에서 모두 이용하고있었는데 

 

Dagger를 사용하면 주입될때마다 새로운 인스턴스가 생성되어서 주입되기때문에 에러가 생기는 것이다. 

 

 

이문제를 해결하기위해서는 Scope를 적용해야하는데 

 

간단하다. 

 

@Singleton
@Component(modules = [StorageModule::class])
interface AppComponent { ... }
@Singleton
class UserManager @Inject constructor(private val storage: Storage) {
    ...
}

 

Component 와 동일한 인스턴스로 생성해야할 클래스를 @Singleton annotation으로 표시해주면 앞으로는 동일한 인스턴스가 주입될것이다. 

 

 

 

참조 : https://developer.android.com/codelabs/android-dagger

'안드로이드' 카테고리의 다른 글

.aar 라이브러리 생성  (1) 2021.11.24
D.I (feat Hilt) 기본 - 1  (0) 2021.11.10
안드로이드 모바일 - 웨어러블 데이터 전송  (0) 2021.11.10