kotlin构建MVVM应用之依赖注入--Koin

2,421 阅读2分钟

在开发的过程中,依赖注入有什么的好处呢?

  • 增加程序重用
  • 模块功能单一
  • 方便测试
  • 需求变更,减少程序开发
  • 充分的解耦合

Koin是一个Kotin极轻量的依赖注入框架,据官方资料显示,它有一下特点

  • 无代理
  • 无代码生成
  • 无反射。

在app\build.gradle中引入依赖

    //koin(依赖注入)
    implementation "org.koin:koin-androidx-scope:2.0.1"
    implementation "org.koin:koin-androidx-viewmodel:2.0.1"
    implementation "org.koin:koin-androidx-ext:2.0.1"


给大家展示一下整体的目录结构

首先,定义我们的model层,定义username和password两个被观察字段

package com.xiangshike.live.model

import androidx.databinding.ObservableField

data class UserModel(
    var username: ObservableField<String> = ObservableField(""),
    var password: ObservableField<String> = ObservableField("")
) {
    override fun toString(): String {
        return "UserModel(username=$username, password=$password)"
    }
}

其次、定义我们的repository层返回我们需要的数据,当然了,你也可以通过网络请求获得数据

package com.xiangshike.live.repository

import androidx.databinding.ObservableField
import com.xiangshike.live.model.UserModel

class UserRepository {
    fun getUser(): UserModel = UserModel(ObservableField("hanyun"), ObservableField("123456"))
}

再次、在我们viewmodel层把repository和model进行关联


package com.xiangshike.live.viewmodel

import androidx.lifecycle.ViewModel
import com.xiangshike.live.model.UserModel
import com.xiangshike.live.repository.UserRepository

class UserViewModel(private val userRepository: UserRepository) : ViewModel() {
    fun getUser(): UserModel = userRepository.getUser()
}

然后、在module中声明注入


package com.xiangshike.live.di

import com.xiangshike.live.repository.UserRepository
import com.xiangshike.live.viewmodel.UserViewModel
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.core.module.Module
import org.koin.dsl.module

val viewModelModule = module {
    viewModel {
        UserViewModel(get())
    }
}
val repositoryModule = module {
    factory<UserRepository> {
        UserRepository()
    }
}
val appModule: List<Module> = listOf(repositoryModule, viewModelModule)

再然后、声明引入我们的注入


package com.xiangshike.live.di

import com.xiangshike.live.repository.UserRepository
import com.xiangshike.live.viewmodel.UserViewModel
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.core.module.Module
import org.koin.dsl.module

val viewModelModule = module {
    viewModel {
        UserViewModel(get())
    }
}
val repositoryModule = module {
    factory<UserRepository> {
        UserRepository()
    }
}
val appModule: List<Module> = listOf(repositoryModule, viewModelModule)

这句为我们自动注入get()自动获得了UserRepository,然后实例化注入进来

    UserViewModel(get())
    

启用注入


package com.xiangshike.live

import android.app.Application
import android.content.ContextWrapper
import com.xiangshike.live.di.appModule
import org.koin.core.context.startKoin

lateinit var mApplication: Application

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        mApplication = this
        startKoin {
            modules(appModule)
        }
    }
}

object Application : ContextWrapper(mApplication)

表示启用注入

        startKoin {
            modules(appModule)
        }

使用


class MainActivity : BaseActivity<ActivityMainBinding>() {
    private val mUserModel: UserModel by lazy { UserModel() }
    private val mUserViewModel: UserViewModel by viewModel()
    override fun getLayoutId(): Int = R.layout.activity_main
    override fun initData() {
        val user: UserModel = mUserViewModel.getUser()
        mUserModel.username = user.username
        mUserModel.password = user.password
        mDataBind.userModel = mUserModel
    }
    override fun initView() {
        loginBtn.setOnClickListener {
            login()
        }
    }
...
}

我们通过下面这句,引入了我们UserViewModel

    private val mUserViewModel: UserViewModel by viewModel()

最终,我们应用启动的时候,给我们的用户和密码设置了默认值,同时实现了view和model的双向绑定。