-
Notifications
You must be signed in to change notification settings - Fork 24
Kodein v4 шпаргалка
Kodein v4 - DI библиотека для Kotlin (и Android).
Документы по теме:
- Официальная документация
- Статья на хабре Kodein — интересная альтернатива Dagger 2 для внедрения зависимостей в Kotlin
На русском информации критически мало. Так что решил для себя набросать шпаргалку, а то когда долго туда не лезу то забываю. От Kodein в целом положительные эмоции. Единственно, что пока напрягает - это слишком большая разрозненность кода когда лезешь в исходники Kodein чтобы с чем-то разобраться, но это скорее всего связано с Kotlin, потому что он такое позволяет.
Итак поехали.
- Factory и Porvider - новый инстенс каждый раз, различаются только наличием параметров (у фабрики)
bind<Message>() with factory { type: Int -> MessageFactory(type) }
bind<Message> with provider { MessageFactory(6) }
-
with singleton
- обычный синглтон, создаётся один раз в момент вызова -
with eagerSingleton
- тоже самое что синглтон, только создаётся как можно раньше (к момент инициализации Kolein) -
with multiton
- мультитон, это фабрика синглтона, для каждого уникального параметра создаётся один инстенс -
with instance()
- связывание с уже готовым объектом, передаётся не функция а уже готовый объект -
Soft & weak singleton or multiton
- в общем используют WeakReference и SoftReference для созданных объектов. -
with refSingleton(threadLocal)
- синглтон на уровне треда, свой интсенс на каждый поток
Тут отдельно. В документации описано всё это как-то поверхностно и кажется сложно когда пытаешься понять как оно работает. Разбираемся.
Scope
- это по сути хранилище объектов. В Kodein он состоит из интерфейса Scope
и класса ScopeRegistry
.
interface Scope<in C> {
fun getRegistry(context: C): ScopeRegistry
}
ScopeRegistry
- это хранилище объектов
context
- это любой объект по которому можно получить соответствующий ScopeRegistry
Отличие в том, что AutoScope хранит в себе ссылку на контекст (вернее есть метод его получения getContext()
) поэтому при with autoScopedSingleton(scope)
для получения инстенса объекта используется kodein.instance<>()
а для with scopedSingleton(scope)
используется фабрика куда надо явно передавать нужный контекст, например kodein.factory<String, Person>()
.
Для более лучшего понимания AutoScope
и Scope
лучше взглянуть на тесты:
@Test fun test16_1_ScopedSingleton() {
val myScope = object : Scope<String> {
val cache = HashMap<String, ScopeRegistry>()
override fun getRegistry(context: String): ScopeRegistry = cache.getOrPut(context) { ScopeRegistry() }
}
val kodein = Kodein {
bind<Person>() with scopedSingleton(myScope) { Person() }
}
val factory = kodein.factory<String, Person>()
val one = factory("one")
val two = factory("two")
assertSame(one, factory("one"))
assertNotSame(one, factory("two"))
assertSame(two, factory("two"))
myScope.cache.remove("one")
assertNotSame(one, factory("one"))
assertSame(two, factory("two"))
}
@Test fun test16_2_AutoScopedSingleton() {
val myScope = object : AutoScope<Unit> {
val registry = ScopeRegistry()
override fun getRegistry(context: Unit) = registry
override fun getContext() = Unit
}
val kodein = Kodein {
bind<Person>() with autoScopedSingleton(myScope) { Person() }
}
val p = kodein.instance<Person>()
assertSame(p, kodein.instance<Person>())
myScope.registry.clear()
assertNotSame(p, kodein.instance<Person>())
}
В Kodein Android используются autoScopedSingleton
, где контекст - это какой либо android компонент, фрагмент, активити и т.д. что позволяет насувать всяких инстенсов через bind<>() with autoScopedSingleton(androidActivityScope)
. Получается при kodein.instance<>()
будет получаться объекты разные например для каждой активити.
На мой взгляд Kodein-Android уж сильно усложнён и ограничен.
В связке с MVP (c Moxy) использование Kodein-Android на самом деле пока вообще не понятно зачем. В презенторах всё равно не получится использовать android-скоупы. Я думаю нужно сделать чтото типа kodein-moxy где реализовать чтото типа presentorScope, чтобы можно было создавать инстансы на уровне презентеров.
Всё, что выше, было про kodein v4, но недавно (сейчас май 2018г) вышел Kodein 5. Я пока его только посмотрел но не сильно вникал. Знаю что поменяли очень много.