-
Notifications
You must be signed in to change notification settings - Fork 0
๐ค AN DI ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- ๊ธฐ์กด ์ฝ๋๋ฅผ ํฐ ์์ ์์ด ๋น ๋ฅด๊ฒ ์ ์ฉ ๊ฐ๋ฅ
- ๋ฐํ์ ์์กด์ฑ ์ฃผ์ ์ด ์ฑ ์ฑ๋ฅ์ ์ํฅ์ ํฌ๊ฒ ๋ผ์น์ง ์์
- Unit Test ์ Koin ์ ํ์ฉํ ์ ์๋ค
- ๋๋ฒ๊น ์ด ์ฌ์
- ํ๋ก์ ํธ ๊ตฌ์กฐ๊ฐ ๋ณต์กํ์ง ์์
- Hilt๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ, ๋ธ๋์น ์ด๋ํ ๋๋ง๋ค ์ปดํ์ผ ์ค๋ฅ ๋ฐ์
๋ฐํ์์ ์์กด์ฑ์ ์ฃผ์
ํ๋ค๋ ๋จ์ ๋๋ฌธ์ ์ฃผ์
ํ
์คํธ
๋ฅผ ํด์ผ๋๋ค๋ ๊ฒฐ์ ์ ๋ด๋ฆผ
- โญ๏ธโญ๏ธ ๋น๋์๊ฐ์ ์ํฅ์ ์์ค๋ค. (vs Hilt ๋ ๋น๋ ํ์์ ์ฝ๋๊ฐ ์์ฑ ๋น๋์๊ฐ์ด ๋์ด๋จ)
- โญ๏ธโญ๏ธ ๊ณต์ ๋ฌธ์๊ฐ ์ง์ง ๊ฐ๋ ์ฑ ์๊ฒ ์ ์ ๋ฆฌ
- โญ๏ธโญ๏ธ Test ๋ ์ฌ์
- โญ๏ธ Only Kotlin ์ธ ์ ์ด ์ฅ์ ์ธ๋ฏ
- ์ฐ๋ฆฌ ์ฑ์ ๋ณต์กํ ๋ฉํฐ ๋ชจ๋ ๊ตฌ์กฐ๊ฐ ์๋๋ค! (๊ทธ๋ ๊ธฐ์ Hilt ์ ์์กด์ฑ ๊ทธ๋ํ๊ฐ ํ์ ์๋ค)
- Debugger ๊ฐ ์ ๋์ํด์ ์์กด์ฑ ํ์ ์ด ๋ก๊น ์ด ์ฌ์ (Hilt ๋ ์ง์ง ์์๋ณด๊ธฐ ํ๋ค๋ค)
- ๐จ๐จ๐จ ๋ฐํ์์ DI๊ฐ ๋์ํ๊ธฐ ๋๋ฌธ์ ์ค์ํ๋ฉด ์ฑ์ด ์ฃฝ๋๋ค -> Test ์ฝ๋๊ฐ ์ง์ง ํ์ ์ผ๋ฏ
- ๐จ๐จ ๊ฐ์ Activity ๋ง๋๋ ค๋ฉด ๊ฐ Activity ๋ง๋ค ScopeID ๋ฅผ ๋ค๋ฅด๊ฒ ํด์ค์ผํจ (๊ทธ๋ฌ๋ ์ด๋ด ์ผ์ด ์์๋ฏ)
- ๐จ๐จ Scope Component ๊ฐ ์ง์ง ์ง์ฆ๋๋ค ๐ฅ ์ข ๋ ๋ฅํ๊ฒ ์๊ธฐํ์๋ฉด, ViewModel ์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๋ฐ๋ฅด๋ ๋ ํฌ์งํ ๋ฆฌ๋ฅผ ๋ง๋ค๊ณ , Activity ์์ by ViewModel() ์ ๋๊ฒจ์ฃผ๊ณ ์ถ์๋๋ฐ ๋ถ๊ฐ๋ฅํจ. ViewModel ๋ด๋ถ์ ์๋น์ค ๋ก์ผ์ดํฐ ํจํด์ผ๋ก ๋ ํฌ์งํ ๋ฆฌ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ์์ผ๋ก ํด๊ฒฐํด์ผํจ ๐จ Hilt ๋ Android Scope ๋ฅผ ์ข ๋ ์น์ ํ๊ฒ ์ง์ํด์ฃผ๋๋ฏ~
- ์์ ํ๋ก์ ํธ์์ ๊ฐ์ฅ ํํ ์ฐ๋ ๊ธฐ๋ฅ๋ค์ ์ง๊ด์ ์ด๋ค. ์ฑ๊ธํค์ผ๋ก ์ฌ์ฉํ๋ ๊ฒ๋ค ํธํ๋ค์.
- ๋น๋ ์๋๊ฐ ๋น ๋ฅด๋ค! ๊ต์ฅํ ์์ ํ๋ก์ ํธ์ฌ์ ๋น๋ ์๋๊ฐ ๋ง์ด ์ฐจ์ด๋๋ค..
- ๋ก๊ทธ ํ์ธ์ด ํธํ๋ค.
-
๋ฐํ์์ DI ๋์ด์ ๋ถ์ํ๋ค. ๊ทธ๋์ ํ ์คํธ ์ฝ๋ ํ์ํ ๋ฏ... ์ด์ฉ๋ฉด..? ํ ์คํธ ์ฝ๋๊ฐ ๊ฐ์ ๋์ด์ ์ฅ์ ์ด ๋ ์๋ ์๊ฒ ๋ค์..?
-
์กฐ๊ธ ๋ณต์กํ ๊ธฐ๋ฅ์ ์ฐ๋ฉด ์คํ๋ ค ๋ ์ด๋ ต๋ค. ์กํฐ๋นํฐ ์ค์ฝํ์, ๋ทฐ๋ชจ๋ธ ์ค์ฝํ์ ์กด์ฌํ๋ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๊ท์ฐฎ๋๋ผ๊ตฌ์.. ์์ ์จ์ผํจ.
-
์๊ฐ๋ณด๋ค ํ๊ตญ ์ฝ์ธ ๊ด๋ จ ๋ ํผ๋ฐ์ค๊ฐ ์๋ค. ์ฝ์ธ ๋ทฐ๋ชจ๋ธ์ค์ฝํ ๋ผ๊ณ ๊ฒ์ํ๋ฉด ์ฝ๋ฃจํด ์ค์ฝํ ๊ด๋ จ ๊ธ๋ง ๋์จ๋ค.
- ์ฝ๊ฐ ๋ณต์กํ ์ค์ฝํ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ ๋ ์คํ๋ ค ํธํ๋ค.
- ๋ทฐ๋ชจ๋ธ ์ค์ฝํ ์ปดํฌ๋ํธ -> @ViewModelScoped
- ์กํฐ๋นํฐ ์ค์ฝํ ์ปดํฌ๋ํธ -> '@ActivityScoped` ์กฐ๊ธ๋ง ๊ณต๋ถํ๋ฉด ์คํ๋ ค ์ฌ์์
์์ ์ฑ
- ์์กด์ฑ ๊ทธ๋ํ๊ฐ ์ด์ํ๊ฒ ์ค์ ๋๋ฉด ์ปดํ์ผ(๋น๋) ํ์์ ํฐ์ ธ์ ์์ฌ์ด ๋ฉ๋๋ค.
๋ํผ๋ฐ์ค ๋ง์
-
๋ฌ๋ ์ปค๋ธ: ์ด์ ์ ์ฌ์ฉํด๋ดค๋๋ฐ๋ ๊ฝค ์ด๋ ค์ ์ต๋๋ค.
-
๋๋ฒ๊น ์ด๋ ค์.. ๋ค๋ฅธ ๋ฌธ์ ๋ก ํฐ์ง๋๋ฐ, ๊ฐ์ ๋น๋ ์๋ฌ ๋ฉ์์ง๊ฐ ๋์์ ์ข ํ๋ค์์ด์.. ๊ทผ๋ฐ ์ ๊ฐ ์ฒ์ ์ฌ์ฉํ์ ๋๋ณด๋ค๋ ๋ ์ข์์ง ๋ฏ?
-
๋น๋ ์๊ฐ (์ฝ์ธ์์ ์ค๋ช ํ ๊ฒ๊ณผ ๊ฐ์)
๊ทธ๋์ ์ ๋ ์ฝ์ธ์ ์ฌ์ฉํ๋ ๊ฒ ์ข์ ๊ฒ ๊ฐ๋ค๋ ์๊ฐ์ด ๋ญ๋๋ค.
Hilt
- ๊ณต์ ๋ฌธ์ ์ฝ๋๋ฉ์ด ์ ๋์ด ์์ด์ ์ฝ๊ฒ ๋ณด๊ณ ๋ฐ๋ผํ ์ ์์์
- ๊ณต์ ๋ฌธ์๋ฟ ์๋๋ผ ์๋ฃ๋ ๋ง์์ ๊ตฌ๊ธ๋ง ํ๊ธฐ๋ ํธํ์
- ๋ญ๊ฐ ์๋๋ก์ด๋ ์นํ์ ์ด๋ ๋๋์ ๋ฐ์์ Scope ๊ด๋ฆฌ๊ฐ ๋ ์ฌ์์ ๊ทธ๋ฐ๊ฐ..
- ๋ง์ ์ ๋ ธํ ์ด์ ๋ฑ ์ ์ฉํด์ผ ํ ๋ฒ ์ด์ค ์ฝ๋๊ฐ ๋ง์์ ๋ค์ ๋ถํธํ๋ฏ
- import๋ฅผ ๊ฐ๋ ๋ชปํ๋๋ฏ ?? ์ฃผ๊ธฐ์ ์ธ clean project, rebuild๊ฐ ํ์ํจ --> ์ด๊ฒ ์ ๋๋ฌธ์ธ๊ฐ์..
Koin
- Logger๋ฅผ ํตํด ์๋ฌ ๋ฐ์ ์, ์๋ฌ ๋ก๊น ์ด ์ฌ์์ ์ข์์
- DSL์ด ์ต์ํ์ง ์์์ ์ ์ฉํ ๋ ๋ถํธํ๋๋ฐ, ์ ์ฉํ๊ณ ๋๋๊น ์ข์๋ณด์ด๋ค..
- ๋น๋์๋๊ฐ ๋ ๋น ๋ฅธ๋ฏ
- ๋ํผ๋ฐ์ค๊ฐ ๋ณ๋ก ์์ด์ ํํธ๋ณด๋ค ์คํ๋ ค ํ์ตํ๋๋ฐ ์ค๋๊ฑธ๋ฆฐ ๋๋
- ๊ตฌ๊ธ์์ ์ง์ํด์ฃผ๋ค๋ณด๋ Android ์ ๊ต์ฅํ ์นํ์ (?) ์ด๋ผ๋ ๋๋์ ๋ง์ด ๋ฐ์๋ค.
- Android Component๋ณ Scope๊ฐ ๋ช ํํ๊ณ ์ง๊ด์ ์ด๋ผ์ ํธํ.
- ์๋๋ก์ด๋ ์คํ๋์ค ์ฌ์ฉ ์ ์ฃผ์ ๊ทธ๋ํ๋ฅผ ๋ช ์์ ์ผ๋ก ํ์ํด์ฃผ์ด์ ๋ณด๊ธฐ ํธํ์ต๋๋ค.
- ์ด๋ฐ์๋ DSL ์ด ์ต์ํ์ง ์์์ผ๋ ๋ค ๊ตฌํํด๋ณด๊ณ ๋์ ๋ณด๋ ์ฝ๋๊ฐ ๊ต์ฅํ ์ฌํํ๋ค! (์ฝ๋ ๊ท๋ชจ๊ฐ ์์์ ๊ทธ๋ฐ๊ฐ..?)
- AAC ViewModel ์ฌ์ฉ ์ ์ฃผ์ ๊ธฐ๋ฅ์ ์ง์ํด์ฃผ์ด์ ๋์์ง ์๋ค!
- scope ์ค์ ์ด ์กฐ๊ธ ๋ฒ๊ฑฐ๋กญ๋ค .... ๐ฅน
// @Bind
scopedOf(::StubCartRepository).bind<CartRepository>()
// @Provide
scoped<CartRepository> { StubCartRepository() }
- ์ฃผ์ ํ ์คํธ๋ Robolectric/Androidx ๋ก ViewModel ์ฃผ์ ํ ์ค๋ง ํ๊ธฐ
@Test
fun `ViewModel ์ฃผ์
ํ
์คํธ`() {
scenario.onActivity { activity ->
activity.getViewModel<MainViewModel>().shouldNotBeNull()
}
}
- ๋ชจ๋ ์ฃผ์ ์ ๋ต
// :app
val appModule = module {
includes(dataModule)
viewModelOf(::CartViewModel)
viewModelOf(::CartViewModel)
viewModelOf(::CartViewModel)
viewModelOf(::CartViewModel)
}
// :data
val dataModule = module {
includes(localModule, remoteModule)
singleOf(::RemoteDataSource)
singleOf(::LocalDataSource)
singleOf(::DefaultCartRepository).binds(CartRepository::class)
singleOf(::DefaultProductRepository).binds(CartRepository::class)
}
// :local
val localModule = module {..}
// :remote
val remoteModule = module {..}
// :testing - test ํ ๋ ์ฌ์ฉ
val testModule = module { }
val appModule = module {
viewModel<CartViewModel> { (id: Int) -> CartViewModel(id, get()) }
}
class MyActivity : AppCompatActivity() {
val viewModel by viewModel<CartViewModel> {
parametersOf(1)
}
}