当前位置: 首页 > 工具软件 > Kodein-DI > 使用案例 >

学习Kodein(二)

喻嘉泽
2023-12-01

Kodein是什么?

在网上关于它的资料并不是很多,这也证明它现在并不是很完善,之所以要写一系列关于Kodein的文章是为保证自己要一直学习新鲜事物。
这篇文章主要介绍Kodein在Android中如何使用
首先我们在app->build.gradle引入

implementation 'org.kodein.di:kodein-di-generic-jvm:6.5.0'
implementation 'org.kodein.di:kodein-di-framework-android-x:6.5.0'

在自定义的Application中实现KodeinAware接口,

class MyApp : Application(), KodeinAware {
    companion object {
        var instance: Application? = null
    }

    override val kodein = Kodein.lazy {
//        bind<Context>() with singleton { this@MyApp }
        import(androidXModule(this@MyApp))

        // 导入自己写的需要全局使用的Module
 //       import(module = moduleActivityManager)
    }

    override fun onCreate() {
        super.onCreate()
        instance = this
    }
}

随便定义一个类

class ActivityManager{
    fun getName(): String = "ActivityManagerClass"
}

定义一个TAG,方便debug调试时使用,命名方式module_tag_className

const val MODULE_TAG_ACTIVITY_MANAGER = "module_tag_activity_manager"
val moduleActivityManager = Kodein.Module(MODULE_TAG_ACTIVITY_MANAGER) {
    bind<ActivityManager>() with singleton {
        ActivityManager()
    }
}

通过上面code我们明确了以下三件事情

  1. 创建TAG
  2. 单例模式
  3. 创建对象

可以看到这比Dagger要简单许多,不用在声明component,module,provider等注解,这更加Kotlin,接下来就是在MainActivity中去使用我们创建ActivityManager实例

class MainActivity : AppCompatActivity(), KodeinAware {
    // closesKodein 函数返回了相邻上层的一个Kodien容器,
    // 对于Activity来说它返回的是Application层级的kodein容器
    private val parentKodein by closestKodein()
    override val kodein: Kodein by retainedKodein {
        // 通过extend()函数,我们将Application层级的Kodien容器也放在了Activity的kodien容器中,
        // 这样activity就能从上层的Kodein容器取出对应依赖
        extend(parentKodein, copy = Copy.All)
        // 定义一个moduleActivityManager以存放MainActivity所需依赖的绑定函数
        import(moduleActivityManager)
        bind<Activity>() with instance(this@MainActivity)
    }
    private val am: ActivityManager by instance()
    private val am2: ActivityManager by instance()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // 这里我们为了证明`singleton`关键字是正确的,我们定义了两个对象进行比较
		println("----------hexl: $am / $am2")
    }
}

上面我们用了singleton这个关键字,但实际开发中我们的对象并不是每一个都需要通过单例去创建这一点毋庸置疑,我们下面一起来看看还有哪些其他的关键字

很简单我们在定义一个UserEntity

class UserEntity {
    fun print() {
        println("----------hexl: hello kodein")
    }
}

UserEntity这个类提供module

const val MODULE_TAG_USER = "module_tag_user"
val moduleUserEntity = Kodein.Module(MODULE_TAG_USER) {
    bind<UserEntity>() with provider {
        UserEntity()
    }
}

这与上面我们创建ActivityManager很相像,但唯一的区别就是我们使用了provider这个关键字而不是singleton这对于我们来说非常重要,接下来我们看看如何在MainActivity中去使用它

class MainActivity : AppCompatActivity(), KodeinAware {
    // closesKodein 函数返回了相邻上层的一个Kodien容器,
    // 对于Activity来说它返回的是Application层级的kodein容器
    private val parentKodein by closestKodein()
    override val kodein: Kodein by retainedKodein {
        // 通过extend()函数,我们将Application层级的Kodien容器也放在了Activity的kodien容器中,
        // 这样activity就能从上层的Kodein容器取出对应依赖
        extend(parentKodein, copy = Copy.All)
        // 定义一个moduleActivityManager以存放MainActivity所需依赖的绑定函数
        import(moduleActivityManager)
        //------------------ 新增代码 ------------------//
        import(moduleUserEntity)
        bind<Activity>() with instance(this@MainActivity)
    }
    private val am: ActivityManager by instance()
    private val am2: ActivityManager by instance()

	//------------------ 新增代码 ------------------//
	private val userEntity: UserEntity by instance()
    private val userEntity2: UserEntity by instance()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // 这里我们为了证明`singleton`关键字是单例模式的,我们定义了两个对象进行比较
		println("----------hexl: $am / $am2")
		// 这里我们为了证明`provider`关键字只提供了对象的创建而不保证对象的全局唯一的,我们定义了两个对象进行比较
		println("----------hexl: $userEntity / $userEntity2")
    }
}
 类似资料: