
Koin is a pragmatic and lightweight dependency injection framework for Kotlin developers.
(Koin은 Kotlin 개발자를 위한 실용적이고 가벼운 종속성 주입(DI) 프레임워크입니다.)
Koin is a DSL, a light container and a pragmatic API
(Koin은 DSL이자 가벼운 컨테이너이자 실용적인 API입니다.) - koin 문서
DSL은 특정 도메인에 국한해 사용하는 언어이다.
따라서, koin은 kotlin에 최적화된 DI 라이브러리입니다
객체 간의 의존성을 외부에서 주입해주는 설계 패턴으로 이를 통해 객체가 다른 객체에 직접 의존하지 않고, 필요한 의존성을 외부에서 주입받아 결합도를 낮춥니다. DI는 코드의 유연성, 재사용성, 테스트 용이성을 높이는 데 기여한다.
MVVM 패턴을 더욱 잘 이용 + 생명주기와 상관없이 데이터 관리
선택한 이유는 쉬워서!! + 팀원들은 DI 경험이 없다고 하기도 해서..
그당시 막 안드로이드를 공부하던 시기여서.. 지금은 단점이 치명적이여서 hilt를 더 선호 합니다..ㅎㅎ
val appModule = module {
single { Dispatchers.IO }
single { Dispatchers.Main }
//network
single { provideNeoulRetrofit(get(), get()) }
single { providerGsonConvertFactory() }
single { buildOkHttpClint() }
//Api
single { provideStoryApiService(get()) }
single { provideBrandApiService(get()) }
single { provideProductApiService(get()) }
//loginApi
single { provideLoginApiService(get()) }
single<LoginRepository> { DefaultLoginRepository(get(), get()) }
//SignUpApi
single { provideSignUpApiService(get()) }
single<SignupRepository> { DefaultSignupRepository(get(), get()) }
//MyPageApi
single { provideMyPageApiService(get()) }
single<MyPageRepository> { DefaultMyPageRepository(get(), get()) }
//Repository
single<StoryRepository> { DefaultStoryRepository(get(), get()) }
single<BrandRepository> { DefaultBrandRepository(get(), get()) }
single<ProductRepository> { DefaultProductRepository(get(), get()) }
//util
single { ApplicationPreferenceManager(androidApplication()) }
single { MainMenuBus() }
single { CategoryMenuBus() }
//VM
viewModel { HomeViewModel(get(), get(), get()) }
viewModel { EventViewModel() }
viewModel { (categoryId: Int, categoryId2: Int) ->
CategoryViewModel(get(), categoryId,categoryId2)
}
viewModel { BrandViewModel(get()) }
viewModel { (brand: BrandItem) -> BrandDetailViewModel(brand, get()) }
viewModel { StoryViewModel(get()) }
viewModel { (story: Story) -> StoryDetailViewModel(story, get()) }
viewModel { MyPageViewModel(get()) }
viewModel { (product: Product) -> ProductViewModel(product, get()) }
viewModel { SearchViewModel(get() ,get()) }
viewModel { LikeListViewModel(get(), get()) }
}
Single : 싱글톤 객체로 생성합니다.
Factory : 요청 시 마다 매번 새로운 객체를 생성한다.
ViewModel : viewModel에 대한 객체를 생성합니다.
get : 컴포넌트 내에서 알맞은 의존성을 주입합니다.
named("~~~") : get() 으로 받을때 동일한 타입의 객체를 구분하기 위해
BrandDetailActivity.kt
class BrandDetailActivity : BaseActivity<BrandDetailViewModel, ActivityBrandDetailBinding>() {
override val viewModel by viewModel<BrandDetailViewModel> {
parametersOf(
intent.getParcelableExtra(BRAND_KEY)
)
}
private val mainMenuBus by inject<MainMenuBus>()
///****///
BrandDetailViewModel.kt
class BrandDetailViewModel(
private val brand: BrandItem,
private val brandRepository: BrandRepository
) : BaseViewModel() {
private var jwt = ""
val brandDetailStateLiveData = MutableLiveData<BrandDetailState>(BrandDetailState.Uninitialized)
val brandLikedLiveData = MutableLiveData<Boolean>(null)
val productListLiveData = MutableLiveData<List<Product>>()
override fun fetchData() = viewModelScope.launch {
** brend detail -> main (brend -> my page) ,
brand detail 엑티비티의 finish 하면서 main 엑티비티의 bottomNavi(fragment) 전환하기 위해 singleton 객체 사용