https://start.insert-koin.io/#/getting-started/modules-definitions
开始
Koin in 5 minutes (5分钟快速入手Koin)
Getting Started (开始)
用Koin编写定义是通过Kotlin函数完成的,该函数描述了实例的构建方式。
配置完Koin应用程序后,让我们来编写一些模块和定义。
给出我们需要去注入的类:
1
2
3
4
| class DataRepository()
interface Presenter
class MyPresenter(val repository : Repository) : Presenter
class HttpClient(val url : String)
|
下面展示如何定义这些组件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| // declare a module
// 定义一个module
val myModule = module {
// Define a singleton for type DataRepository
// 为DataRepository定义一个单例
single { DataRepository() }
// Define a factory (create a new instance each time) for type Presenter (infered parameter in <>)
// Resolve constructor dependency with get()
// 为Presenter(在<>中推断类型)定义一个factory(每次都创建一个新的实例)
// 使用 get() 解析构造函数依赖
factory<Presenter> { MyPresenter(get()) }
// Define a singleton of type HttpClient
// inject property "server_url" from Koin properties
// 定义一个HttpClient类的单利
// 从Koin属性中注入"server_url"这个属性
single { HttpClient(getProperty("server_url")) }
}
|
你可以给组件提供一个修饰符。这个修饰符可以是string或者type,并通过 named()
函数进行配置:
1
2
3
4
5
6
7
8
9
| val myModule = module {
// Define a singleton for type DataRepository
// 为DataRepository定义一个单例
single { DataRepository() }
// Mock
single(named("mock")) { MockDataRepository() }
}
|
修饰符可以与枚举类关联,也可以直接与类型关联:
1
2
3
4
5
| // Type qualifier
single(named<MyClass>()) { MockDataRepository() }
// Enum qualifier
single(named<MyEnum.MyValue>()) { MockDataRepository() }
|
在DLS模块中,对于一个定义,你可以使用 bind
操作符(KClass列表使用 binds
)来给定一些额外的类型去绑定:
1
2
3
| module {
single { Component1() } bind ComponentInterface1::class
}
|
然后你就能通过 get<Component1>()
或者 get<ComponentInterface1>()
来请求到你的实例了。
你也能给多个定义绑定同一个type:
1
2
3
4
| module {
single { Component1() } bind ComponentInterface1::class
single { Component2() } bind ComponentInterface1::class
}
|
但是在这你不能通过 get<Simple.ComponentInterface1>()
来请求一个实例。你只能使用 koin.bind<Component1,ComponentInterface1>()
来检索一个具有 Component1
实现的 ComponentInterface1
的实例。
请注意,您还可以查找绑定给定类型的所有组件: getAll<ComponentInterface1>()
将请求所有绑定 ComponentInterface1
类的实例。
Koin没有导入(import)的概念。所以只需结合几个互补的模块定义。
让我们在两个模块中分发定义:
1
2
3
4
5
6
| val module1 = module {
single { DataRepository() }
}
val module2 = module {
factory<Presenter> { MyPresenter(get()) }
}
|
我们只需要为Koin列出他们:
1
2
3
| startKoin {
modules(module1,module2)
}
|
在Koin通过 startKoin { }
函数启动后,我们还可以使用 loadKoinModules(modules...)
函数来加载其它定义模块。
一旦一个模块被加载到了Koin中,我们就可以取消加载他然后删除掉与这些定义相关的定义和实例。为此,我们可以使用 unloadKoinModules(modules...)
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| val module = module {
single { (id: Int) -> Simple.MySingle(id) }
}
startKoin {
printLogger(Level.DEBUG)
modules(module)
}
get<Simple.MySingle> { parametersOf(42) } -> id is 42
// unload definitions for given module
unloadKoinModules(module)
// load definitions for given module
loadKoinModules(module)
get<Simple.MySingle> { parametersOf(24) } -> id is 24
|
Koin 1.0的最后一个向后移植*(译者注:原文是backport)*功能之一是能够动态声明实例。现在可以在Koin.declare()或Scope.declare()上使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
| val koin = koinApplication {
// no def
modules()
}.koin
// Create an instance
val a = Simple.ComponentA()
// declare it
koin.declare(a)
// retrieve it
assertEquals(a, koin.get<Simple.ComponentA>())
|
你也能通过一个修饰符或者次要类型来帮助你创建定义:
koin.declare(myInstance, named("qualifier"))
koin.declare(myInstance, secondaryTypes = listOf())
快速回顾下这些Koin关键字:
module { }
- 创建一个Koin模块或者子模块(在一个模块里面)factory { }
- 提供一个 factory工厂 bean定义single { }
- 提供一个bean定义get()
- 解析一个组件依赖named()
- 通过type、枚举或者字符串来定义一个修饰符bind
- 给给定的bean定义绑定其它Kolin类型binds
- 给给定的bean定义绑定其他Kotlin类型列表getProperty()
- 解析一个Koin属性