Skip to content

Kodein v4 шпаргалка

Roman edited this page Jun 2, 2018 · 1 revision

Kodein v4 - DI библиотека для Kotlin (и Android).

Документы по теме:

На русском информации критически мало. Так что решил для себя набросать шпаргалку, а то когда долго туда не лезу то забываю. От 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) - синглтон на уровне треда, свой интсенс на каждый поток

Scoped singletons

Тут отдельно. В документации описано всё это как-то поверхностно и кажется сложно когда пытаешься понять как оно работает. Разбираемся.

Scope - это по сути хранилище объектов. В Kodein он состоит из интерфейса Scope и класса ScopeRegistry.

interface Scope<in C> {
    fun getRegistry(context: C): ScopeRegistry
}

ScopeRegistry - это хранилище объектов context - это любой объект по которому можно получить соответствующий ScopeRegistry

Понимание AutoScope и Scope

Отличие в том, что 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

В Kodein Android используются autoScopedSingleton, где контекст - это какой либо android компонент, фрагмент, активити и т.д. что позволяет насувать всяких инстенсов через bind<>() with autoScopedSingleton(androidActivityScope). Получается при kodein.instance<>() будет получаться объекты разные например для каждой активити.

На мой взгляд Kodein-Android уж сильно усложнён и ограничен.

Про Kodein Android и MVP Moxy

В связке с MVP (c Moxy) использование Kodein-Android на самом деле пока вообще не понятно зачем. В презенторах всё равно не получится использовать android-скоупы. Я думаю нужно сделать чтото типа kodein-moxy где реализовать чтото типа presentorScope, чтобы можно было создавать инстансы на уровне презентеров.

Kodein 5

Всё, что выше, было про kodein v4, но недавно (сейчас май 2018г) вышел Kodein 5. Я пока его только посмотрел но не сильно вникал. Знаю что поменяли очень много.

Clone this wiki locally