koin依赖注入框架


koin的使用

添加依赖库

    implementation 'org.koin:koin-androidx-viewmodel:2.0.1'
    implementation 'org.koin:koin-android:2.0.1'

需要创建依赖对象

这里创建三个类,Student,SchoolCourse,Friend。

  • Student类

依赖于SchoolCourse,Friend类的方法。

class Student(val course: SchoolCourse,val friend: Friend) {
    fun beSmart() {
        course.study()
        friend.hangout()
    }
}
  • SchoolCourse类

提供方法 study 负责打印 “I am studying”

class SchoolCourse {
    fun study() {
        println("I am studying")
    }
}
  • Friend 类

提供方法 hangout 负责打印 “We’re hanging out”

class Friend {
    fun hangout() {
        println("We're hanging out")
    }
}

定义依赖集合

创建 Modeles 文件

  • 需要使用 module 方法

提供所需要的依赖

  • 需要 signle 方法

使当前依赖为一个单例的对象

  • 需要 factory 方法

定义一个工场每次调用创建一个新的实例

  • 需要 get() 方法

get 用于最终实现注入

val appModule: Module = module {
    single { SchoolCourse() }
    factory { Friend() }
    factory { Student(get(), get()) }
}

启动 Koin

  • 需要系统在创建时第一个启动Application实例

    修改 application 中的 name 属性 使得应用第一个启动它

  • 需要创建 MyApp

第一个启动的Application实例

  • 需要 startKoin

用来启动Koin

  • 需要 modules

注册声明的Module

  • 需要 androidContext

向Koin中注入context

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        startKoin {
            androidContext(this@MyApp)
            modules(listOf(appModule))
        }
    }
}

使用 koin 实现注入

在需要注入的地方使用

  • 需要使用 get()

非 懒加载,注入实例

通过 注入依赖完成后的实例调用beSmart()方法

        val student = get<Student>()
        student.beSmart()
        val student2 = get<Student>()
        student2.beSmart()

完成注入

什么是 koin?

一个轻量级的依赖注入组件。

补充

Koin in Android: 更简单的依赖注入

Get

get()用于实现注入。

当你所属类型不确定时,可以指定类型。get()

声明:绑定一个接口

一个 single 或者 factory 声明将会使用其给定的 lambda 表达式类型。比如 single{T},该声明所匹配的类型就是表达式所声明的类型 T 让我们以一个类及其实现的接口为例:

// Service interface
interface Service{

    fun doSomething()
}

// Service Implementation
class ServiceImp() : Service {

    fun doSomething() { ... }
}

在koin模块(module),我们可以使用Kotiln下的 as 操作符。如下所示:

val myModule = module {

    // 只匹配 Service 类型
    single { ServiceImp() }

    // 只匹配 Service 类型
    single { ServiceImp() as Service }

}

你也可以使用推断类型表达式

val myModule = module {

    // 只匹配 Service 类型
    single { ServiceImp() }

    // 只匹配 Service 类型
    single<Service> { ServiceImp() }

}

第二种风格是首选的,在接下来的文档中,也会使用该方法。

Bind

  • bind() - 为给定的对象声明添加要绑定的类型

    Bind 是一个中辍函数,可以用于把一个Service关联到多个类。例如现在有两个接口:Tool,Flammable,Stove实现了这两个接口。显然如果只定义1个Service是不能同时注入Stove和这两个接口的。

    这是就可以发挥Bind的作用了

    val myModule = module{
        factory { Stove() } bind Tool::class bind Flammable::class // <- here!
    
        factory { Chef(get()) }
    }

    这么一来,下面的三个注入都是合法的,并都会得到一个 Stove 实例:

    val chef: Chef = get()
    val tool:Tool = get()
    val flammable:Flammable = get()

named

限定符,用来区别同一个类的不同实例

使用

 single(named("dev")) { DataRepository() }
 single(named("test")) { DataRepository() }

name 属性

可通过name或者class检索到对应的实例

使用

    factory(name = MAIN) {
        AndroidSchedulers.mainThread()
    }

依赖注入和控制反转

依赖注入(Dependency Injection,简称 DI)

什么是依赖注入?

假设 A 是 耳机,B 是播放器。

当 A 依赖 B 时(也就是耳机需要播放以音乐时),A 要想播放音乐就必须要有B的实例,也就是

  1. 通过A的接口,把B传入;
  2. 通过A的构造,把B传入;
  3. 通过A的属性,把B传入;

这些过程叫做依赖注入(DI)

控制反转(Inversion of Control,简称 Ioc)

但是 A 并不能控制 B 何时播放(创建)或者关闭(销毁),仅使用 B ,那么 B 的控制权交给 A 之外的事务处理,这些叫做 控制反转(Ioc)

为什么需要依赖注入

降低耦合

什么是耦合

耦合性(Coupling),也叫耦合度,是对模块间关联程度的度量。两个或多个功能模块之间的关联程度。

什么是解耦

解除类(模块)之间的直接关系,将直接关系转换成间接关系

引用:

Dependency Injection with Koin - Android Kotlin tutorial

koin 中文 DOC

Koin in Android: 更简单的依赖注入

如果有些方法没有详细说明你可以自行搜索查看


文章作者: TheCara
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明来源 TheCara !
 上一篇
RxJava2 Android 中使用 RxJava2 Android 中使用
什么是RxJava实现异步操作的库 定义RxJava 是基于事件流的、实现异步操作的库 作用实现异步操作 使用添加依赖 implementation "io.reactivex.rxjava2:rxjava:2.2.6&qu
2020-08-21
下一篇 
BottomSheet、BottomShaeetDialog使用流程 BottomSheet、BottomShaeetDialog使用流程
BottomSheetDemo 代码 https://medium.com/@droidbyme/android-bottom-sheet-7e9cfcec6427使用 BottomSheet、BottomSheetDialog、Botto
2020-08-06 TheCara
  目录