Skip to content
Roman edited this page Sep 13, 2018 · 12 revisions

Недавно перевёл проект на Toothpick. Решил частично перевести документацию и сделать основные заметки что к чему.

toothpick/wiki

Scopes

Scope - это одна из основных концепций в Toothpick. Scope - это по сути контейнер (хранилище). Там хранятся ссылки на созданные scoped-объекты (об этом позже), а также биндинги (правила что и как создавать). Скоупы можно выстраивать в деревья. Каждый скоуп может иметь детей.

Scopes, создание инстенсов и инъекции

В Toothpick инъекции и создание инстенсов всегда выполняется в рамках скоупа. Тоесть когда мы хотим создать экземпляр кокогото класса в который должны заинжектится зависимости, то мы всегда должны указать скоуп. Toothpick будет отталкиваться от этого скоупа при инъекции полей в этот класс.

Биндинги

Есть 2 типа биндингов - Scoped & Unscoped.

bind(IFoo.class).to(Foo.class) // Unscoped

bind(IFoo.class).toInstance(foo) // Scoped
bind(IFoo.class).to(Foo.class).instancesInScope() // Scoped
bind(IFoo.class).to(Foo.class).singletonInScope() // Scoped

Всё просто, Scoped привязывают созданные объекты к скоупу а Unscoped нет. При Unscoped всегда будет создан новый экземпляр в том скоупе который указали.

Ниъекции в рамках скоупа

Рассмотрим следующий пример

//a class using field and method injections
class Foo {
  @Inject Bar bar;
  @Inject void setQurtz(Qurtz qurtz) {...}
}

//injecting an object in a scope
val scope = Toothpick.openScope("APP_SCOPE")
Toothpick.inject(new Foo(), scope);

======================

Получить текущий скоуп

Можно заинжектить в класс сам скоуп. Это удобно когда например Presenter хочет сам закрыть скоуп в onDestroy() но не знает где взять его имя (объект скоупа)

class MyPresenter @Inject constructor( private val foo : Foo) {
  @Inject scope: Scope;
   
  override fun onDestroy() {
        super.onDestroy()
        Toothpick.closeScope(scope.name)
  }
}

instancesInScope() и singletonInScope()

Официальная дока https://github.com/stephanenicolas/toothpick/wiki/Scoped-&-Unscoped-Bindings

bind(IFoo.class).to(Foo.class).instancesInScope()
bind(IBar.class).to(Bar.class).singletonInScope()
bind(Car.class).to(Bar.class)

Смысл xxxInScope() в том, что экземпляр Foo создастся только в том скоупе, где его биндили, даже если инжектили дочерним скоупом.

Если у нас есть два скоупа, S1->S2 (S1 родитель для S2) и в S1 есть биндинг Foo помеченный как xxxInScope(), то Toothpick.inject(new A(), S2) приведёт к тому, что экземпляр Foo будет создан в скоупе S1 а не в S2. Если бы xxxInScope() не был указать, то экземпляр Foo создался бы в S2.

Отличие instancesInScope() от singletonInScope() только в том, что при singletonInScope() экземпляр создаётся один раз и хранится в скоупе и раздаётся при каждом инжекте один и тот же. А при instancesInScope() экземпляр создаётся новый при каждом инжекте.

Clone this wiki locally