在 Compose 中使用 Koin 进行依赖注入

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 的魅力!

一起成长!😆

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

全套视频资料:

一、面试合集

在这里插入图片描述
二、源码解析合集
在这里插入图片描述

三、开源框架合集
在这里插入图片描述

欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取↓↓↓

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值