Open veldic opened 3 years ago
koin 에서 context injection 은 미리 정의된 androidApplication()
으로 가져올 수 있습니다.
val repositoryModule = module {
single { TokenRepository(androidApplication(), get()) }
}
아래 이슈를 참고하세요 https://github.com/InsertKoinIO/koin/issues/190
음... context 는 activity 의 context 일 수도 있고, service 의 context 일 수도 있고, application 의 context 일 수도 있습니다. 이때 activity 의 context 로 Db instance 를 만들게 되면 해당 activity 가 destroy 되고 나서도 그 activity 의 context 를 db 가 가지고 있어 제대로 가비지 컬렉션 되지 않는 문제도 발생할 수 있습니다. 따라서 singleton 한 db instance 에 적절한 (같은 singleton 느낌인) applicationContext 가 적절할 것 같네요.
네 koin, dagger 와 같은 di 라이브러리에서 해주는 일을 직접 코드로 작성한 셈이죠.
추가로, 이번 과제에서는 persist 하게 유지해야하는 정보가 user token (더 커봤자 user model) 정도로 꼭 room db 를 사용할 필요까지는 없다고 느껴집니다. 따라서 sharedPreference 를 활용해 좀 더 가벼운 코드로 persistance 를 유지시켜도 좋은 방향일 것 같습니다.
@sanggggg 아 2번 질문은 1번 질문에 연결되어 질문드린건데요, 2번의 코드 부분에서 application의 context를 이용해야 한다는 것을 인지하였기 때문에 1번 질문에서 application context를 받아올 수 있다면 2번 질문과 같이 수정해서 사용하면 되는 것인가에 대한 질문이었습니다! 아마 답변해주신 내용을 보니 가능한 방식이라는 생각은 드네요
(파일의 구조가 의도하셨던 것과 다르다면 그 부분도 지적해주시면 감사하겠습니다! 구현하다보니 무언가 잘못되어가는 것을 느끼고 있어서요... TokenRepository가 아니라 LoginRepository 등으로 만들어 내부에서 Token을 따로 처리해야될 것 같다는 생각이 들었습니다.)
이번 과제에서 token을 발급받은 뒤, persist하게 유지하여야 하는 조건이 있었습니다. 이를 구현하기 위해 TokenRepository에서 Retrofit으로 http 통신을 통해 token 등을 받아오는 작업 및 room database에 저장하는 작업을 진행하려 합니다.
이 과정에서 Injection을 이용하려고 했는데 맞게 구현하고 있는 것인지 궁금하여 issue를 남깁니다. SimpleTodo 과제와 MovieDB 과제를 참고하여 진행중입니다.
https://github.com/wafflestudio/rookies/blob/e6b1718b0697f050e6a608bd8a7cb389bf480a30/android/assignment3/MovieDb/app/src/main/java/com/example/moviedb/repository/MovieRepository.kt#L5 MovieDB에서는 retrofit 사용을 위해 service를 받아오기 때문에 위와 같이 코드가 작성되어 https://github.com/wafflestudio/rookies/blob/e6b1718b0697f050e6a608bd8a7cb389bf480a30/android/assignment3/MovieDb/app/src/main/java/com/example/moviedb/di/RepositoryModule.kt#L8 이렇게 injection을 해 주었고
https://github.com/wafflestudio/rookies/blob/e6b1718b0697f050e6a608bd8a7cb389bf480a30/android/assignment2/SimpleTodo/app/src/main/java/com/sanggggg/simpletodo/room/TodoRepository.kt#L7 SimpleTodo에서는 Room database 사용을 위해 context를 받아와서 위와 같이 작성되었고 https://github.com/wafflestudio/rookies/blob/e6b1718b0697f050e6a608bd8a7cb389bf480a30/android/assignment2/SimpleTodo/app/src/main/java/com/sanggggg/simpletodo/utils/InjectionUtils.kt#L10-L16 https://github.com/wafflestudio/rookies/blob/1fce5892df9d10d93b1eb12546df100593e3767d/android/assignment2/SimpleTodo/app/src/main/java/com/sanggggg/simpletodo/ui/MainActivity.kt#L27-L29 이렇게 MainActivity의 context가 넘어가는 것을 확인하였습니다.
그렇다면 저는 retrofit과 RoomDB를 함께 구현하기 위해서 context와 service를 함께 받아와야 한다고 판단하였습니다. 그래서 TokenRepository를 다음과 같이 구현하였습니다.
class TokenRepository(context: Context, private val service : TokenService)
이 repository에 injection해주기 위해 RepositoryModule을 다음과 같이 설정했습니다.val repositoryModule = module { single { TokenRepository(get(), get()) } }
위처럼 구현하게 된다면 SeminarManagerApplication에서 applicationContext가 TokenRepository에 Injection 된다고 생각했습니다.그렇다면 SimpleTodo 코드에 있는 https://github.com/wafflestudio/rookies/blob/1fce5892df9d10d93b1eb12546df100593e3767d/android/assignment2/SimpleTodo/app/src/main/java/com/sanggggg/simpletodo/room/TodoDatabase.kt#L20-L26 위 부분에서
context.applicationContext
를context
로 단순히 사용할 수 있을 것 같는데 맞는 방식인지 질문드립니다.약간 늦은 질문일 수 있는데 SimpleTodo에서 InjectionUtils.kt를 사용한 이유는 단순히 Koin을 사용하지 않은 채로 DI를 구현했기 때문인가요?