# Kotlin Injection
[TOC]
**Koin**
目前理解:用来集中定义于一处,整理view model, 变数集中於一个地方
官網
https://insert-koin.io/
RayWender大大(較推)
https://www.raywenderlich.com/9457-dependency-injection-with-koin
//build.gradle
implementation 'org.koin:koin-android:2.1.5'
implementation 'org.koin:koin-androidx-scope:2.1.5'
implementation 'org.koin:koin-androidx-viewmodel:2.1.5'
## Application 啟動,module可以有很多種
```kotlin=
startKoin {
androidContext(this@SMBFApplication)
modules(listOf(sportModule, repositoryModule))
}
```
## 定義module
```kotlin=
val repositoryModule = module {
//GameDetail
factory { GameDetailRepo(get()) }
//Betting
factory { BettingRepo(get()) }
//也有這種的
viewModel { GameViewModel() }
viewModel { ProgramViewModel(get()) }
}
```
## 需要實作class
```kotlin=
//factory
class GameDetailRepo(val service: GameDetailService) {
fun postGameDetail(gameDetailBo: GameDetailBo) = service.postGameDetail(gameDetailBo)
fun postAllGame(allGameBo: GameDetailBo) = service.postAllGame(allGameBo)
}
//viewmodel
class ProgramViewModel(private val matchRepo: MatchRepo) : BaseViewModel(), KoinComponent {
}
```
## 打API的service
```kotlin=
interface GameDetailService {
@POST("app/member_API/api_doaction.php")
fun postGameDetail(@Body gameDetailBo: GameDetailBo): Single<GameDetailResp>
@POST("app/member_API/api_doaction.php")
fun postAllGame(@Body allGameBo: GameDetailBo): Single<AllGameResp>
}
```
## 資料長的樣子根據會收到的JSON格式(使用moshi)
```kotlin=
@JsonClass(generateAdapter = true)
data class GameDetailBo(
val Method: String,
val Request: Request
)
```
```kotlin=
@JsonClass(generateAdapter = true)
data class GameDetailResp(
val GameData: List<GameData>?,
val cmd: Cmd,
val respcode: String,
val respmsg: String?,
val timestamp: String
)
```
## factory用的時候,在某一個ViewModel內,不需要繁瑣創建,直接by inject()
```kotlin=
fun postAllGame(allGameRequest: Request) {
val gameDetailRepo: GameDetailRepo by inject()
gameDetailRepo.postAllGame(
GameDetailBo(
"getAllGame",
allGameRequest
)
).ioToUi().subscribe({ dto ->
},
{ t: Throwable? -> onAllGame.value = Resource.error(t?.message, null) }
).addTo(compositeDisposable)
}
```
## 在某個Fragment裡
```kotlin=0
//連動LiveData
private fun initObserver() {
gameViewModel.onAccountLogin.observe(viewLifecycleOwner, Observer {
when (it.status) {
Status.SUCCESS -> {
it.data?.let { accountLoginData ->
val gToken = accountLoginData.redirectURL.toUri().getQueryParameter("gToken")
gToken?.let {
Properties.gameUid = gToken
getGameInfo()
} ?: run {
showErrorMsg(getString(R.string.game_token_fail))
}
}
}
Status.ERROR -> {
val errorMsg = it.message ?: getString(R.string.game_token_fail)
showErrorMsg(errorMsg)
}
}
})
}
//呼叫factory
private fun getGameInfo() {
gameDetailInfo?.let { gameDetailInfo ->
val calendar = MatchUtils.getCalendar()
val iPAddress = Utils.getIPAddress(true)
val allGameRequest = AllGameRequest(
gameDetailInfo.gameDate,
gameDetailInfo.ballType.name,
"",
Langx.ZH_CN.value,
iPAddress,
gameDetailInfo.competitionType.type,
calendar.timeInMillis.toString(),
Properties.gameUid
)
viewModel.postAllGame(allGameRequest)
} ?: run {
showErrorMsg()
}
}
```
## viewModel用的時候
```kotlin=
private val viewModel by viewModel<LoginViewModel>()
val phoneArea = phoneLayout.phoneAreaLabel.text.toString().replace("+", "")
val phone = phoneLayout.phoneNumberEt.getPhoneNumber(phoneArea)
viewModel.getOtp(phoneArea, phone)
```
**Anko**
目前理解:写code方式编辑UI,代替layout xml
Good Extension
RxJavaExt.kt

File list

List.kt

專案檔案結構範例
