The pragmatic Kotlin & Kotlin Multiplatform Dependency Injection framework

实用的Kotlin和Kotlin多渠道依靠注入框架

Android Studio环境为 Android Studio Flamingo | 2022.2.1

Koin的最新版别为3.4.5

Compose 最新安稳版别为1.4.3

在前面的文章中,咱们介绍了在 Android 中(非 Compose)工程中怎么去运用 Koin 进行依靠注入,最近正好想开发一个 Compose版 Wan Android App,在依靠注入的功能中,仍是决定运用 Koin 来办理依靠注入,本篇正好介绍下 Koin 怎么在 Compose 中完成依靠注入

Android运用Koin依靠项注入 – 第一弹

Android运用Koin依靠项注入 – 第二弹

Koin 注入一般目标

Koin 的初始化就不再多说了,第一篇文章中现已介绍的很清楚了,下面咱们看下关于 Compose,Koin 需求额外添加的依靠

implementation "io.insert-koin:koin-androidx-compose:3.4.5"

在 app 的build.gradle文件中添加上面的依靠,将 koin-compose 添加到工程中。

下面咱们来看看在@Composable办法中怎么注入一个一般的目标示例

注入根本目标

// 简单的一个日志输出类
class Logger {
    fun print(msg: String) {
        Log.d(TAG, "Logger print: $msg")
    }
}
val module = module {
  	// 设置它的注入类型为单例
    single { Logger() }
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
  	// 经过 koin 的 koinInject()办法进行目标注入
    val logger: Logger = koinInject()
    Text(
        text = "Hello $name!",
        modifier = modifier.clickable { logger.print("greeting") }
    )
}
# 日志输出
Logger print: greeting

从上面的代码中能够看到,module{}在一般工程和 compose 工程中用法是一致的,仅仅在获取依靠目标时,compose 中需求运用 koinInject() 办法来获取,此办法也是被@Composable修饰,并且经过remember()来完结内部逻辑完成。

由此能够看出,在 compose 中经过 koin 完成依靠注入也是十分简单的,并且内部完成也不杂乱,接下来看看怎么经过限定符获取不同场景的目标示例。

绑定限定符

koin 中能够运用qualifier来限定同一个目标不同的实例注入,下面仍是经过 Logger目标来展示下限定符的效果。

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
  	// 经过获取目标时,增加限定符 qualifier 参数
    val logger: Logger = koinInject(qualifier = qualifier("single1"))
    val logger2: Logger = koinInject(qualifier = qualifier("single2"))
    Text(
        text = "Hello $name!",
        modifier = modifier.clickable {
            logger.print("greeting")
            logger2.print("greeting")
        }
    )
}
class Logger {
    fun print(msg: String) {
      	// 打印的当地增加了 hashcode 值,能够方便观察目标是否为同一个
        Log.d(TAG, "Logger print: $msg, ${hashCode()}")
    }
}
val module = module {
  	// 限定符为 single1
    single(qualifier = qualifier("single1")) { Logger() }
  	// 限定符为 single2
    single(qualifier = qualifier("single2")) { Logger() }
}

module 中,即便两个 Logger 目标都是选用单例模式,但是它们两个的限定符值不同,此刻咱们想一下是否会注入两个不同的单例目标呢,一会看下日志的输出就会明白了。同时咱们在获取注入的目标时,也需求加上 qualifier参数,不然在运行之后会抛出异常,koinInject()办法的第一个参数便是 qualifier,这里咱们传入在 module 中界说过的限定符值即可。

Logger print: greeting, 105740997
Logger print: greeting, 63142938

经过日志就能够显而易见的看出,即便经过 single{} 来办理了依靠注入,但是在限定符的效果下, 获取的时分仍是会根据限定符生成不同的目标实例。

这样咱们在日常开发中就能够经过限定符来办理咱们想要的注入目标了。

Koin 注入 ViewModel 目标

Koin 也帮助咱们在运用 ViewModel 的过程中提供了依靠注入的便捷办法,无论是有参仍是无参的 ViewModel目标,关于 Koin 来说都为咱们提供了便捷的操作。

咱们先界说两个 ViewModel 目标,一个无参另外一个带有 Logger 参数的构造办法

class KoinViewModel : ViewModel() {
    fun print() {
        Log.d(TAG, "KoinViewModel print")
    }
}
class KoinParamsViewModel(
    private val logger: Logger
) : ViewModel() {
    fun print() {
        logger.print("KoinParamsViewModel")
    }
}

然后在 moudle 中办理这两个注入的办法

val module = module {
    single(qualifier = qualifier("single1")) { Logger() }
    single(qualifier = qualifier("single2")) { Logger() }
    viewModel { KoinViewModel() }
    viewModel { KoinParamsViewModel(get(qualifier = qualifier("single1"))) }
}

无论是无参仍是有参的 ViewModel 都是经过 viewModel{} 扩展函数来注入,只不过有参的直接经过 get() 办法将参数传入即可,这个在前面的文章中也有说到,注入目标的参数不需求在获取的时分传入,只需求在 module 界说的时分直接绑定就行了,这样就能够做到咱们只管拿来用,不必去管怎么完成的。

最终咱们再来看看怎么获取和运用注入的 ViewModel

@Composable
fun Greeting(
    name: String, modifier: Modifier = Modifier,
    koinViewModel: KoinViewModel = org.koin.androidx.compose.koinViewModel(),
    koinParamsViewModel: KoinParamsViewModel = org.koin.androidx.compose.koinViewModel()
) {
    Text(
        text = "Hello $name!",
        modifier = modifier.clickable {
            koinViewModel.print()
            koinParamsViewModel.print()
        }
    )
}
#
KoinViewModel print
Logger print: KoinParamsViewModel, 69574952

想要获取ViewModel目标,只需求调用 koinViewModel() 办法就好,不必管是否有参数需求传递,Koin 会主动为咱们将所需求的参数赋值过去,经过后边日志也能够表示咱们 ViewModel 目标注入成功了。

其实在 Compose 工程中,Koin 仅仅简单的增加了一些特别的注入办法,帮助咱们更好的办理和运用注入目标,好了,到此为止 Koin 在 Compose 中怎么运用依靠注入现已介绍完了,咱们感兴趣的能够在 Demo 中体验体验下 Koin 的魅力!

一同成长!