依赖注入框架——Koin
一、带着问题去学习
1.1 什么是依赖注入
初学者可能会想,“什么是依赖注入?”
这是名词分析。依赖项是高层模块必须使用(依赖)底层模块的函数。在编程语言中,这可以通过继承、创建底层模块类的实例等来实现。注入意味着底层模块的实例可以自动提供给更高层的模块使用。
简而言之,这样做的目的就是为了减少与类对象的耦合,将依赖倒置原则落实到设计模式中(如果你对这个设计模式不熟悉,请参考我之前的博客)请:6大原则详解设计模式)。也就是说,如果需要修改类对象,则无法修改依赖实例。事实上,类构造函数通常需要参数。这是一个注入(通过构造函数注入)。类中经常使用的set() 方法也是一种注入。
1.2 为什么要引入第三方的注入控件
说到这里,可能有同学会问,“我天天用,为什么还要引用第三方的注入控件呢?”
如果有一天你需要向这个类的构造函数添加另一个参数怎么办?如果你有这个类的100 个实例,如果你一一改变它们会怎样?这是很不现实的。或者,如果几个月后,另一个构造参数被添加到类中呢?这就是我引用依赖注入控制的原因。
1.3 什么是Koin
为Kotlin 开发人员提供的实用、轻量级依赖注入框架。用纯Kotlin 编写,仅使用函数分辨率:没有代理、代码生成或反射。
为Kotlin 开发人员提供的实用、轻量级依赖注入框架。它是用纯Kotlin 编写的,仅使用函数分析。它不使用代理、代码生成或反射。
简单来说,Koin 是一个可以让你更好地管理依赖注入并实现自动化依赖注入的框架。
二、如何使用Koin
Koin中依赖注入的基本流程:
添加Koin 依赖项:将Koin 依赖项添加到项目的build.gradle 文件中。这通常包括Koin 的核心库和您可能需要的任何扩展库,例如Android 相关库。定义Koin模块
通过创建一个或多个Koin 模块来配置依赖注入。这些模块通常定义在单独的文件中,并使用Koin 的DSL 语法来定义需要注入的类以及它们之间的关系。模块可以使用single、factory 和viewModel 等关键字定义如何插入不同类型的对象。例如,single用于插入单例对象,factory用于插入每次请求时创建新实例的对象,viewModel用于插入绑定到Android ViewModel生命周期的对象。
初始化Koin
在应用程序的入口点初始化Koin,例如Android 应用程序类或JVM 应用程序的main 函数。调用startKoin方法,传入一个或多个Koin模块。此方法还允许您执行其他配置,例如启用日志记录和绑定Android 上下文。
注入依赖项
如果需要依赖注入,可以使用Koin提供的扩展函数或API来获取依赖对象。对于Android应用程序,您可以使用viewModel()和inject()等扩展函数将依赖项注入到您的activity、fragment或ViewModel中。对于非Android 应用程序,您可以使用Koin.get() 方法来检索依赖对象。
使用依赖项
一旦有了依赖对象,就可以像使用任何其他对象一样使用它。请小心地在适当的时候停止Koin(例如在Android 应用程序的onDestroy 方法中)。但是,通常对于简单的应用程序,此步骤可能不是必需的。
(可选)清理Koin:一旦您的应用程序不再需要Koin,您可以通过调用stopKoin() 方法来清理Koin 的资源。然而,对于大多数应用程序来说,这一步可能不是必需的,因为Koin 会自动管理生命周期。
2.1 添加 Koin 依赖
将Koin的Android相关依赖添加到app/build.gradle文件中。
依赖项{
//Koin AndroidX 作用域函数
实现\’io.insert-koin:koin-androidx-scope:X.Y.Z\’ //将X.Y.Z 替换为最新版本
//Koin AndroidX ViewModel 功能
实现\’io.insert-koin:koin-androidx-viewmodel:X.Y.Z\’ //将X.Y.Z 替换为最新版本
//硬币AndroidX Ext
实现\’io.insert-koin:koin-androidx-ext:X.Y.Z\’ //将X.Y.Z 替换为最新版本
//Koin的核心特性
实现\’io.insert-koin:koin-core:X.Y.Z\’ //将X.Y.Z 替换为最新版本
}
2.2 定义Koin模块
在使用Module之前,我们先介绍一下Module有哪些方法。
Method 函数Factory{ } 常规注入,以工厂方式定义(每次构造一个新对象) single{ } 单例注入(全局只存在一个对象) viewModel{ }viewModel 注入,这一点尤其是Koin 是ViewModel 提供的作用域{ }scoped 定义了一个范围。 { }在范围内使用get()。 {} 自动检索依赖对象名称() 并定义用于限定符的名称。
需要注入的对象可以写入模块文件中。
通过创建名为AppModule.kt 的文件来定义Koin 模块
//应用程序模块.kt
包com.example.myapp.di
导入com.example.myapp.repository.GreetingRepository
导入com.example.myapp.service.GreetingService
导入org.koin.dsl.module.module
val appModule=模块{
单{ GreetingRepository() }
单个{ GreetingService(get()) }
}
2.3 初始化Koin
在Android 应用程序类的onCreate 方法中初始化Koin。
//我的应用程序.kt
包com.example.myapp
导入android.app.Application
导入com.example.myapp.di.appModule
导入org.koin.android.ext.koin.androidContext
导入org.koin.android.ext.koin.androidLogger
导入org.koin.core.context.startKoin
类MyApplication : 应用程序(){
重写fun onCreate() {
超级.onCreate()
//初始化硬币
开始Koin {
androidLogger() //(可选)启用Koin 日志记录
androidContext(this@MyApplication) //绑定Android上下文
module(listOf(appModule)) //加载定义的模块
}
}
}
2.4 注入和使用依赖
2.4.1 在 ViewModel 中注入依赖
(可选)如果您使用的是ViewModel,则可以像这样注入依赖项:
//GreetingViewModel.kt
包com.example.myapp.viewmodel
导入androidx.lifecycle.ViewModel
导入androidx.lifecycle.ViewModelProvider
导入com.example.myapp.service.GreetingService
导入org.koin.androidx.viewmodel.ext.android.viewModel
类GreetingViewModel(私有valgreetingService: GreetingService) : ViewModel() {
//.ViewModel 中的其他代码.
}
//为ViewModel创建一个工厂
类GreetingViewModelFactory(private valgreetingService: GreetingService) : ViewModelProvider.Factory {
有趣的T : 重写ViewModel? create(modelClass: ClassT): T {
返回GreetingViewModel(greetingService) 作为T
}
}
//获取activity或fragment中的ViewModel
val viewModel: GreetingViewModel by viewModels {
//提供lambda 来获取GreetingService 的实例
GreetingViewModelFactory(get())
}
注意:如果使用Koin的viewModel()函数,则不需要自己实现ViewModelFactory。可以使用viewModels() 将ViewModel 直接插入到ViewModel 中。
2.4.2 在 Activity 或 Fragment 中注入和使用依赖
在活动中注入和使用依赖项
//MainActivity.kt
包com.example.myapp.ui.main
导入android.os.Bundle
导入androidx.appcompat.app.AppCompatActivity
导入com.example.myapp.service.GreetingService
导入org.koin.androidx.scope.lifecycleScope
导入org.koin.androidx.viewmodel.ext.android.viewModel
导入org.koin.core.KoinComponent
导入org.koin.core.inject
类MainActivity : AppCompatActivity(),KoinComponent {
private valgreetingService: GreetingService byject() //注入GreetingService
覆盖fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//使用greetingService
问候语服务.greet()
}
}
请注意,使用KoinComponent 接口时,您可以使用ject() 直接将依赖项注入到任何类中,而无需在startKoin 调用中指定该类的实例。但是,对于活动和片段,更常见的是使用生命周期范围(在片段中)来确保依赖项的生命周期与组件的生命周期相匹配。
2. 在fragment中注入和使用依赖
//MyFragment.kt
包com.example.myapp.ui.fragment
导入android.os.Bundle
导入androidx.fragment.app.Fragment
导入androidx.fragment.app.viewModels
导入androidx.lifecycle.ViewModelProvider
导入com.example.myapp.service.GreetingService
导入com.example.myapp.viewmodel.GreetingViewModel
导入org.koin.androidx.scope.lifecycleScope
导入org.koin.androidx.viewmodel.ext.android.viewModel
导入org.koin.core.KoinComponent
导入org.koin.core.inject
类MyFragment : Fragment(), KoinComponent {
private valgreetingService: GreetingService byject() //注入GreetingService
//或者使用ViewModel
private val viewModel: GreetingViewModel by viewModels()
重写fun onCreateView(
inflater:布局充气机,
container: 查看组?
SavedInstanceState: 捆绑包?
): 次浏览?
//.
//使用greetingService或viewModel
问候语服务.greet()
//.
返回查看
}
//在Fragment中使用自定义ViewModelFactory时
//你可能需要指定
有趣的重写getViewModelStore(): ViewModelStore {
返回ViewModelStore(lifecycleScope.lifecycleOwner)
}
重写fun onViewModelStoreCleared() {
super.onViewModelStoreCleared()
//清理资源(如果需要)
}
}
在片段中使用viewModels() 函数插入ViewModel 也很常见。这是因为该函数自动处理ViewModel 生命周期。但是,如果您需要自定义ViewModel 创建过程(例如,通过使用自定义ViewModelFactory),则可能需要重写getViewModelStore() 和onViewModelStoreCleared() 方法。
以上关于#Dependency Injection Framework ——Koin的相关内容来源网络,仅供参考。相关信息请参见官方公告。
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91834.html