轻量级依赖注入框架koin简析
说到依赖注入框架,Android开发者一定最先想到dagger2,但是dagger2是Java的产物,Android的开发语言已经向kotlin切换,虽然Java与kotlin是完全兼容的,但是基于kotlin语言的一些优异特性一定能诞生出许多更适用于kotlin语言环境的新的框架来,koin正是其中一个。
- 什么是Koin?
Koin是用于Kotlin开发人员(实际也可用于Java开发中)的实用轻量级依赖注入框架。用纯Kotlin编写,仅使用方法来解决问题:无代理,无代码生成,无反射。Koin是一个DSL,一个轻量级容器和一个实用的API。
github地址:https://github.com/InsertKoinIO/koin
- 如何在项目中使用:
将koin-core依赖项添加到Gradle项目
// Add Jcenter to your repositories if neededrepositories { jcenter()}dependencies { // Koin for Android implementation 'org.koin:koin-android:1.0.2'}
得益于Kotlin语言的强大功能,koin提供了一个DSL(domain-specific language)来帮助我们描述应用,而不是添加注解或为其生成代码。这些注解最终还是需要代码来分析,从而进行(动态)代理或者生成代码。而使用Kotlin DSL,我们可以使用智能功能API来实现相同的目标:进行依赖注入。
Koin的使用非常简单,下面我们通过一个实例来展示如何快速注入:
首先我们创建一个接口
interface LoginService { fun login() fun unLogin()}
接着我们创建接口的实现
class LoginServiceImpl:LoginService { override fun login() { println("login") } override fun unLogin() { println("unLogin") }}
然后我们声明这个组件
class KoinApplication: Application() { private val loginModule = module { single { LoginServiceImpl() }//以单例模式声明将这个组件定义绑定到LoginService } override fun onCreate() { super.onCreate() startKoin(this, arrayListOf(loginModule))//将声明的组件注册到koin }}
接下来我们就可以使用koin来为我们注入组件了
只要在要使用的Activity,Fragment等应用组件中添加如下注入声明
private val loginService: LoginService by inject()
koin会通过懒加载的方式,在使用该实例时为我们注入LoginServiceImpl的实例。
当然也可以不通过懒加载,直接获得实例
private val loginService: LoginService = get()
当然,组件定义也可以是带参数的
private val loginModule = module { single { (code: String) ->LoginServiceImpl(code) }//声明将这个组件定义绑定到LoginService }
在注入时,传入注入所需参数即可
private val loginService: LoginService by inject { parametersOf("123") }
全部调用代码:
class MainActivity : AppCompatActivity() { private val loginService: LoginService by inject { parametersOf("123") } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) loginService.login() loginService.unLogin() }}
熟悉依赖注入框架的朋友可能都知道,在Java中,依赖注入通常使用注解,依靠动态代理,或者apt,或者反射来实现注入功能,那么koin不依靠上面的技术是如何做到这一切的呢。
答案就是依靠kotlin特有的特性扩展函数,当然也得益于kotlin对于函数式编程的支持,让koin的代码更加简洁。
将组件注册到容器中后,其原理为将一个组件实例化的方法实例,存储在容器中。
在调用inject()注入的时候,通过组件的定义(单例还是factory),以及绑定的类型(实例化方法绑定到哪个接口或者类型)匹配到对应的生成器(注册的实例化方法),然后通过扩展函数的形式,在Android组件(Activity,Fragment等)中实例化注入。
这里的inject方法是ComponentCallbacks接口的扩展函数,而ComponentCallbacks是所有Android应用组件都继承的几口,所以,能在ComponentCallbacks的实现组件中进行inject注入。
这种新的依赖注入方式,也为我们项目中的架构优化提供了更多的想象空间。
比如对于网络请求,可以让具体的请求方式与业务调用隔离。
这种思想类似于服务开发,只需要向外暴露出使用的接口,具体实现方案调用方并不用关心。
更多相关文章
- 基于 CentOS 使用 Jenkins 实现 Android(安卓)持续集成
- Android开发之旅:应用程序基础及组件
- 【生命周期】Android中Activity的生命周期
- react-native的兼容性(Android、Ios)
- Android单元测试—UI测试(Espresso)
- Android通过Aidl调用Service实例
- Android解析中国天气接口JSon数据,应用于天气查询
- Android自带音乐播放器代码分析(1)
- parse push 消息推送学习笔记(Android消息推送解决方案 备选)