SlideShare a Scribd company logo
1 of 169
Download to read offline
МИХАИЛ
КРЕСТЬЯНИНОВ
АНДРОИД РАЗРАБОТЧИК
t.me/krest_m
DAGGER’A?
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ
NO MORE!
2
DAGGSTASY
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
АГЕНДА
▸DEPENDENCY INJECTION
▸ИНТРО:
▸LIGHTSABER vs KODEIN vs TOOTHPICK
LIGHTSABER
KODEIN
TOOTHPICK
3
INVERSION
OF
CONTROL
DEPENDENCY
INVERSION
PRINCIPLE
DEPENDENCY
INJECTION
"HOLLYWOOD PRINCIPLE: DON'T CALL US, WE'LL CALL YOU"
DEPENDENCY INJECTION - реализация DIP.
Инструмент передачи классу его
зависимостей.
4
"HOLLYWOOD PRINCIPLE”:
DON'T CALL US, WE'LL CALL YOU
5
"HOLLYWOOD PRINCIPLE”:
DON'T CALL US, WE'LL CALL YOU
5
class Tweeter {
fun tweet(message: String) {
val api: TweeterApi = TweeterApi()
api.sendTweet(message)
}
}
"HOLLYWOOD PRINCIPLE”:
DON'T CALL US, WE'LL CALL YOU
5
class Tweeter {
fun tweet(message: String) {
val api: TweeterApi = TweeterApi()
api.sendTweet(message)
}
}
"HOLLYWOOD PRINCIPLE”:
DON'T CALL US, WE'LL CALL YOU
class Tweeter(val api: TweeterApi) {
fun tweet(message: String) {
api.sendTweet(message)
}
}
6
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
ТЕКУЩАЯ СИТУАЦИЯ НА РЫНКЕ
7
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
ТЕКУЩАЯ СИТУАЦИЯ НА РЫНКЕ
DAGGER MONOPOLY
7
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
АГЕНДА
▸DEPENDENCY INJECTION
▸ИНТРО:
▸LIGHTSABER vs KODEIN vs TOOTHPICK
LIGHTSABER
KODEIN
TOOTHPICK
8
LIGHTSABER
MICHAELROCKS/LIGHTSABER
▸ Текущая версия
▸ Мотивация
▸ Главная особенность
9
LIGHTSABER
MICHAELROCKS/LIGHTSABER
10
▸ Текущая версия
0.9.0-beta
▸ Мотивация
▸ Главная особенность
LIGHTSABER
MICHAELROCKS/LIGHTSABER
11
▸ Текущая версия
▸ Мотивация
▸ Главная особенность
Лёгкий и быстрый DI
& Compile Time
& Не зависящий от APT
LIGHTSABER
MICHAELROCKS/LIGHTSABER
12
▸ Текущая версия
▸ Мотивация
▸ Главная особенность
Использует патчинг
байткода вместо
Annotation Processing
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
АГЕНДА
▸DEPENDENCY INJECTION
▸ИНТРО:
▸LIGHTSABER vs KODEIN vs TOOTHPICK
LIGHTSABER
KODEIN
TOOTHPICK
13
KODEIN
SALOMONBRYS/KODEIN
14
▸ Текущая версия
▸ Мотивация
▸ Главная особенность
KODEIN
SALOMONBRYS/KODEIN
15
▸ Текущая версия
4.0.0
▸ Мотивация
▸ Главная особенность
KODEIN
SALOMONBRYS/KODEIN
16
▸ Текущая версия
▸ Мотивация
▸ Главная особенность
DSL-декларативный DI
& Идиоматичный
& Debuggable + Docs
KODEIN
SALOMONBRYS/KODEIN
17
Простота в использовании
& Kotlin friendly
▸ Текущая версия
▸ Мотивация
▸ Главная особенность
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
АГЕНДА
▸DEPENDENCY INJECTION
▸ИНТРО:
▸LIGHTSABER vs KODEIN vs TOOTHPICK
LIGHTSABER
KODEIN
TOOTHPICK
18
TOOTHPICK
STEPHANENICOLAS/TOOTHPICK
19
▸ Текущая версия
▸ Мотивация
▸ Главная особенность
TOOTHPICK
STEPHANENICOLAS/TOOTHPICK
20
▸ Текущая версия
1.0.7
▸ Мотивация
▸ Главная особенность
TOOTHPICK
STEPHANENICOLAS/TOOTHPICK
21
▸ Текущая версия
▸ Мотивация
▸ Главная особенность
Проще, чем Dagger
& Тестируемость
& Scope
TOOTHPICK
STEPHANENICOLAS/TOOTHPICK
22
Тестируемость из коробки
& 2 DAGs
▸ Текущая версия
▸ Мотивация
▸ Главная особенность
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
АГЕНДА
▸DEPENDENCY INJECTION
▸ИНТРО:
▸LIGHTSABER vs KODEIN vs TOOTHPICK
LIGHTSABER
KODEIN
TOOTHPICK
23
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A? 24
LIGHTSABER
VS
KODEIN
VS
TOOTHPICK
▸ОСНОВНЫЕ ПРИНЦИПЫ
▸ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
▸SCOPES
▸ТЕСТИРОВАНИЕ
LIGHTSABER VS KODEIN VS TOOTHPICK 25
КРИТЕРИИ
ОСНОВНЫЕ ПРИНЦИПЫ
LIGHTSABER
26
ОСНОВНЫЕ ПРИНЦИПЫ
LIGHTSABER
26
ОСНОВНЫЕ ПРИНЦИПЫ
LIGHTSABER
▸Lightsaber работает на
основе JSR 330
26
ОСНОВНЫЕ ПРИНЦИПЫ
LIGHTSABER
▸Lightsaber работает на
основе JSR 330
▸Аннотация
вешается на конструктор,
поле или метод класса
@Inject
26
LIGHTSABER
ОСНОВНЫЕ ПРИНЦИПЫ
val injector = Lightsaber.get()
.createInjector(
AppComponent(app = this)
)
injector.injectMembers(this)
27
LIGHTSABER
ОСНОВНЫЕ ПРИНЦИПЫ
val injector = Lightsaber.get()
.createInjector(
AppComponent(app = this)
)
injector.injectMembers(this)
28
LIGHTSABER
ОСНОВНЫЕ ПРИНЦИПЫ
val injector = Lightsaber.get()
.createInjector(
AppComponent(app = this)
)
injector.injectMembers(this)
29
val injector = Lightsaber.get()
.createInjector(
AppComponent(app = this)
)
injector.injectMembers(this)
LIGHTSABER
ОСНОВНЫЕ ПРИНЦИПЫ 30
ОСНОВНЫЕ ПРИНЦИПЫ
KODEIN
31
ОСНОВНЫЕ ПРИНЦИПЫ
KODEIN
31
ОСНОВНЫЕ ПРИНЦИПЫ
KODEIN
▸Лёгкий старт
31
ОСНОВНЫЕ ПРИНЦИПЫ
KODEIN
▸Лёгкий старт
▸Java-only @Inject
31
ОСНОВНЫЕ ПРИНЦИПЫ
KODEIN
▸Лёгкий старт
▸Java-only
▸Runtime-проверка графа
@Inject
31
ОСНОВНЫЕ ПРИНЦИПЫ
KODEIN
▸Лёгкий старт
▸Java-only
▸Runtime-проверка графа
▸Kodein Kotlin
@Inject
31
ОСНОВНЫЕ ПРИНЦИПЫ
val kodein = Kodein {
import(appModule(this@App))
}
val injector = KodeinInjector()
val prefs: SharedPreferences by injector.instance()
override fun onCreate() {
super.onCreate()
injector.inject(kodein)
}
32
KODEIN
ОСНОВНЫЕ ПРИНЦИПЫ
val kodein = Kodein {
import(appModule(this@App))
}
val injector = KodeinInjector()
val prefs: SharedPreferences by injector.instance()
override fun onCreate() {
super.onCreate()
injector.inject(kodein)
}
33
KODEIN
ОСНОВНЫЕ ПРИНЦИПЫ
val kodein = Kodein {
import(appModule(this@App))
}
val injector = KodeinInjector()
val prefs: SharedPreferences by injector.instance()
override fun onCreate() {
super.onCreate()
injector.inject(kodein)
}
34
KODEIN
ОСНОВНЫЕ ПРИНЦИПЫ
val kodein = Kodein {
import(appModule(this@App))
}
val injector = KodeinInjector()
val prefs: SharedPreferences by injector.instance()
override fun onCreate() {
super.onCreate()
injector.inject(kodein)
}
35
KODEIN
ОСНОВНЫЕ ПРИНЦИПЫ
val kodein = Kodein {
import(appModule(this@App))
}
val injector = KodeinInjector()
val prefs: SharedPreferences by injector.instance()
override fun onCreate() {
super.onCreate()
injector.inject(kodein)
}
36
KODEIN
ОСНОВНЫЕ ПРИНЦИПЫ
val kodein = Kodein {
import(appModule(this@App))
}
val injector = KodeinInjector()
val prefs: SharedPreferences by injector.instance()
override fun onCreate() {
super.onCreate()
injector.inject(kodein)
}
37
KODEIN
ОСНОВНЫЕ ПРИНЦИПЫ 38
TOOTHPICK
ОСНОВНЫЕ ПРИНЦИПЫ 38
TOOTHPICK
ОСНОВНЫЕ ПРИНЦИПЫ 38
TOOTHPICK
▸Toothpick работает на
основе JSR 330
ОСНОВНЫЕ ПРИНЦИПЫ 38
TOOTHPICK
▸Toothpick работает на
основе JSR 330
▸Аннотация
вешается на конструктор,
поле или метод класса
@Inject
ОСНОВНЫЕ ПРИНЦИПЫ
val scope = Toothpick.openScopes(app, this)
scope.installModules(ActivityModule(this))
Toothpick.inject(this, scope)
39
TOOTHPICK
ОСНОВНЫЕ ПРИНЦИПЫ
val scope = Toothpick.openScopes(app, this)
scope.installModules(ActivityModule(this))
Toothpick.inject(this, scope)
40
TOOTHPICK
ОСНОВНЫЕ ПРИНЦИПЫ
val scope = Toothpick.openScopes(app, this)
scope.installModules(ActivityModule(this))
Toothpick.inject(this, scope)
41
TOOTHPICK
ОСНОВНЫЕ ПРИНЦИПЫ
val scope = Toothpick.openScopes(app, this)
scope.installModules(ActivityModule(this))
Toothpick.inject(this, scope)
42
TOOTHPICK
▸ОСНОВНЫЕ ПРИНЦИПЫ
▸ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
▸SCOPES
▸ТЕСТИРОВАНИЕ
LIGHTSABER VS KODEIN VS TOOTHPICK 43
КРИТЕРИИ
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ 44
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ 44
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
▸Constructors
44
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
▸Constructors
▸Module
44
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
▸Constructors
▸Module
▸Component
44
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ 45
@Module
class MainModule(val app: Application) {
@Provides
@Singleton
@Named(Tag.APPLICATION_CONTEXT)
private fun context(): Context = app
@Provides
private fun presenter(repo: Repository): Presenter
= PresenterImpl(repo)
}
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
@Module
class MainModule(val app: Application) {
@Provides
@Singleton
@Named(Tag.APPLICATION_CONTEXT)
private fun context(): Context = app
@Provides
private fun presenter(repo: Repository): Presenter
= PresenterImpl(repo)
}
46
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
@Module
class MainModule(val app: Application) {
@Provides
@Singleton
@Named(Tag.APPLICATION_CONTEXT)
private fun context(): Context = app
@Provides
private fun presenter(repo: Repository): Presenter
= PresenterImpl(repo)
}
47
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
@Module
class MainModule(val app: Application) {
@Provides
@Singleton
@Named(Tag.APPLICATION_CONTEXT)
private fun context(): Context = app
@Provides
private fun presenter(repo: Repository): Presenter
= PresenterImpl(repo)
}
48
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
@Component
class AppComponent(
val app: Application
) {
@Provides
fun provideAppModule()
= AppModule(app)
}
49
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
@Component
class AppComponent(
val app: Application
) {
@Provides
fun provideAppModule()
= AppModule(app)
}
50
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
@Component
class AppComponent(
val app: Application
) {
@Provides
fun provideAppModule()
= AppModule(app)
}
51
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ 52
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
▸ Lazy injections
@Inject
lateinit var presenter: Lazy<Presenter>
52
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
▸ Lazy injections
@Inject
lateinit var presenter: Lazy<Presenter>
52
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
@Inject
lateinit var presenter: Provider<Presenter>
▸ Lazy injections
@Inject
lateinit var presenter: Lazy<Presenter>
52
▸ Provider injections
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
@Inject
lateinit var presenter: Provider<Presenter>
▸ Lazy injections
@Inject
lateinit var presenter: Lazy<Presenter>
52
▸ Provider injections
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
@Inject
lateinit var presenter: Provider<Presenter>
▸ Lazy injections
@Inject
lateinit var presenter: Lazy<Presenter>
52
▸ Provider injections
▸ Custom Scope & Qualifiers
LIGHTSABER
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ 53
KODEIN
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ 53
KODEIN
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
▸Modules, Modules, Modules…
53
KODEIN
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
Kodein.Module {
import(module = sampleModule)
bind<Context>(Tag.APP_CONTEXT) with singleton {
app
}
bind<Repository>() with singleton {
RepositoryImpl(
context = instance(Tag.APP_CONTEXT),
sharedPreferences = instance()
)
}
}
54
KODEIN
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
Kodein.Module {
import(module = sampleModule)
bind<Context>(Tag.APP_CONTEXT) with singleton {
app
}
bind<Repository>() with singleton {
RepositoryImpl(
context = instance(Tag.APP_CONTEXT),
sharedPreferences = instance()
)
}
}
55
KODEIN
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
Kodein.Module {
import(module = sampleModule)
bind<Context>(Tag.APP_CONTEXT) with singleton {
app
}
bind<Repository>() with singleton {
RepositoryImpl(
context = instance(Tag.APP_CONTEXT),
sharedPreferences = instance()
)
}
}
56
KODEIN
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
Kodein.Module {
import(module = sampleModule)
bind<Context>(Tag.APP_CONTEXT) with singleton {
app
}
bind<Repository>() with singleton {
RepositoryImpl(
context = instance(Tag.APP_CONTEXT),
sharedPreferences = instance()
)
}
}
57
KODEIN
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
Kodein.Module {
import(module = sampleModule)
bind<Context>(Tag.APP_CONTEXT) with singleton {
app
}
bind<Repository>() with singleton {
RepositoryImpl(
context = instance(Tag.APP_CONTEXT),
sharedPreferences = instance()
)
}
}
58
KODEIN
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
Kodein.Module {
import(module = sampleModule)
bind<Context>(Tag.APP_CONTEXT) with singleton {
app
}
bind<Repository>() with singleton {
RepositoryImpl(
context = instance(Tag.APP_CONTEXT),
sharedPreferences = instance()
)
}
}
59
KODEIN
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ 60
KODEIN
▸ Factory
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
bind<RandomUtil>() with factory { num: Int ->
FakeRandom(num)
}
60
KODEIN
▸ Factory
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
bind<RandomUtil>() with factory { num: Int ->
FakeRandom(num)
}
60
KODEIN
▸ Provider
▸ Factory
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
bind<RandomUtil>() with factory { num: Int ->
FakeRandom(num)
}
bind<RandomUtil>() with provider {
FakeRandom(2)
}
60
KODEIN
▸ Provider
▸ Factory
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
bind<RandomUtil>() with factory { num: Int ->
FakeRandom(num)
}
bind<RandomUtil>() with provider {
FakeRandom(2)
}
60
KODEIN
▸ Provider
▸ And many others
▸ Factory
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
bind<RandomUtil>() with factory { num: Int ->
FakeRandom(num)
}
bind<RandomUtil>() with provider {
FakeRandom(2)
}
60
KODEIN
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ 61
TOOTHPICK
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ 61
TOOTHPICK
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
▸Constructors
61
TOOTHPICK
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
▸Constructors
▸Module
61
TOOTHPICK
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
class Module(val app: Application) : Module() {
init {
bind(Context ::class.java)
.withName(Tag.APP_CONTEXT)
.toInstance(app)
bind(Repository ::class.java)
.to(RepositoryImpl ::class.java)
.singletonInScope()
}
}
62
TOOTHPICK
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
class Module(val app: Application) : Module() {
init {
bind(Context ::class.java)
.withName(Tag.APP_CONTEXT)
.toInstance(app)
bind(Repository ::class.java)
.to(RepositoryImpl ::class.java)
.singletonInScope()
}
}
63
TOOTHPICK
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
class Module(val app: Application) : Module() {
init {
bind(Context ::class.java)
.withName(Tag.APP_CONTEXT)
.toInstance(app)
bind(Repository ::class.java)
.to(RepositoryImpl ::class.java)
.singletonInScope()
}
}
64
TOOTHPICK
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
class Module(val app: Application) : Module() {
init {
bind(Context ::class.java)
.withName(Tag.APP_CONTEXT)
.toInstance(app)
bind(Repository ::class.java)
.to(RepositoryImpl ::class.java)
.singletonInScope()
}
}
65
TOOTHPICK
class Module(val app: Application) : Module() {
init {
bind(Context ::class.java)
.withName(Tag.APP_CONTEXT)
.toInstance(app)
bind(Repository ::class.java)
.to(RepositoryImpl ::class.java)
.singletonInScope()
}
}
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ 66
TOOTHPICK
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
bind(Interface ::class.java)
.to****(Class ::class.java)
67
TOOTHPICK
ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
bind(Interface ::class.java)
.to****(Class ::class.java)
68
TOOTHPICK
▸ОСНОВНЫЕ ПРИНЦИПЫ
▸ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
▸SCOPES
▸ТЕСТИРОВАНИЕ
LIGHTSABER VS KODEIN VS TOOTHPICK 69
КРИТЕРИИ
SCOPES 70
LIGHTSABER
SCOPES 70
LIGHTSABER
SCOPES
▸Аннотации по JSR 330
70
LIGHTSABER
SCOPES
▸Аннотации по JSR 330
70
LIGHTSABER
@Scope
@Documented
@Retention(RUNTIME)
public @interface Singleton {}
SCOPES
▸Аннотации по JSR 330
70
LIGHTSABER
@Scope
@Documented
@Retention(RUNTIME)
public @interface Singleton {}
@Module
class AppModule(val app: Application) {
@Provides
@Singleton
private fun context(): Context = app
}
SCOPES 71
LIGHTSABER
SCOPES
@Singleton
class PresenterImpl()
72
LIGHTSABER
SCOPES 73
KODEIN
SCOPES 73
KODEIN
SCOPES
▸Bindigs & Module
73
KODEIN
bind<Repository>() with singleton {
RepositoryImpl(
context = instance(APP_CONTEXT),
api = instance()
)
}
SCOPES
▸Bindigs & Module
73
KODEIN
bind<Repository>() with singleton {
RepositoryImpl(
context = instance(APP_CONTEXT),
api = instance()
)
}
SCOPES
▸Bindigs & Module
73
KODEIN
SCOPES 74
TOOTHPICK
SCOPES 74
TOOTHPICK
SCOPES
Место, где выполняются
инъекции
SCOPE
74
TOOTHPICK
SCOPES
val scope = Toothpick.openScope(this)
scope.installModules(AppModule(this))
Toothpick.inject(this, scope)
Toothpick.closeScope(this)
Место, где выполняются
инъекции
SCOPE
74
TOOTHPICK
SCOPES
val scope = Toothpick.openScope(this)
scope.installModules(AppModule(this))
Toothpick.inject(this, scope)
Toothpick.closeScope(this)
Место, где выполняются
инъекции
SCOPE
74
TOOTHPICK
val scope = Toothpick.openScope(this)
scope.installModules(AppModule(this))
Toothpick.inject(this, scope)
Toothpick.closeScope(this)
SCOPES
Место, где выполняются
инъекции
SCOPE
75
TOOTHPICK
SCOPES
SCOPE BINDINGSModule
76
TOOTHPICK
val scope = Toothpick.openScope(this)
scope.installModules(AppModule(this))
Toothpick.inject(this, scope)
Toothpick.closeScope(this)
SCOPES 77
TOOTHPICK
SCOPES
APPLICATION
SCOPE
ACTIVITY
SCOPE
FRAGMENT 2
SCOPE
FRAGMENT 1
SCOPE
FRAGMENT 3
SCOPE
77
TOOTHPICK
bind(Context ::class.java).toInstance(app)
bind(Repository ::class.java)
.to(RepositoryImpl ::class.java)
.singletonInScope()
SCOPES 78
TOOTHPICK
bind(Context ::class.java).toInstance(app)
bind(Repository ::class.java)
.to(RepositoryImpl ::class.java)
.singletonInScope()
SCOPES 78
TOOTHPICK
bind(Context ::class.java).toInstance(app)
bind(Repository ::class.java)
.to(RepositoryImpl ::class.java)
.singletonInScope()
SCOPES 79
TOOTHPICK
SCOPES 80
TOOTHPICK
SCOPES
▸ Аннотации по JSR 330
80
TOOTHPICK
SCOPES
▸ Аннотации по JSR 330
▸ Кастомные аннотации
80
TOOTHPICK
SCOPES
▸ Аннотации по JSR 330
▸ Кастомные аннотации
@javax.inject.Scope
@Documented
@Retention(AnnotationRetention.RUNTIME)
annotation class PresenterScope
80
TOOTHPICK
SCOPES
▸ Аннотации по JSR 330
▸ Кастомные аннотации
val scope = Toothpick.openScopes(
application,
PresenterScope ::class.java,
this)
@javax.inject.Scope
@Documented
@Retention(AnnotationRetention.RUNTIME)
annotation class PresenterScope
80
TOOTHPICK
SCOPES
▸ Аннотации по JSR 330
▸ Кастомные аннотации
val scope = Toothpick.openScopes(
application,
PresenterScope ::class.java,
this)
@javax.inject.Scope
@Documented
@Retention(AnnotationRetention.RUNTIME)
annotation class PresenterScope
80
TOOTHPICK
▸ОСНОВНЫЕ ПРИНЦИПЫ
▸ДЕКЛАРАЦИЯ ЗАВИСИМОСТЕЙ
▸SCOPES
▸ТЕСТИРОВАНИЕ
LIGHTSABER VS KODEIN VS TOOTHPICK 81
КРИТЕРИИ
ТЕСТИРОВАНИЕ 82
LIGHTSABER
ТЕСТИРОВАНИЕ 82
LIGHTSABER
ТЕСТИРОВАНИЕ
▸ Нужно просто переопределять
все необходимые модули в
тестах
82
LIGHTSABER
ТЕСТИРОВАНИЕ
▸ Нужно просто переопределять
все необходимые модули в
тестах
@Module
class Module {
@Provides
private fun presenter(): MainPresenter
= FakePresenter()
}
82
LIGHTSABER
ТЕСТИРОВАНИЕ 83
KODEIN
ТЕСТИРОВАНИЕ 83
KODEIN
ТЕСТИРОВАНИЕ
▸ Флаг allowOverride = true
83
KODEIN
ТЕСТИРОВАНИЕ
class TestApp : App() {
override val kodein: Kodein by lazy {
Kodein {
import(
module = appModule(this@TestApp),
allowOverride = true
)
constant("TEST", overrides = true) with 4L
}
}
}
▸ Флаг allowOverride = true
83
KODEIN
ТЕСТИРОВАНИЕ
class TestApp : App() {
override val kodein: Kodein by lazy {
Kodein {
import(
module = appModule(this@TestApp),
allowOverride = true
)
constant("TEST", overrides = true) with 4L
}
}
}
▸ Флаг allowOverride = true
83
KODEIN
ТЕСТИРОВАНИЕ 84
TOOTHPICK
ТЕСТИРОВАНИЕ 84
TOOTHPICK
ТЕСТИРОВАНИЕ
▸Киллер-фича
84
TOOTHPICK
ТЕСТИРОВАНИЕ
▸Киллер-фича
@Mock
private lateinit var repository: Repository
@Rule
@JvmField
var toothPickRule = ToothPickRule(this, app)
84
TOOTHPICK
ТЕСТИРОВАНИЕ
▸Киллер-фича
@Mock
private lateinit var repository: Repository
@Rule
@JvmField
var toothPickRule = ToothPickRule(this, app)
84
TOOTHPICK
ТЕСТИРОВАНИЕ
▸Киллер-фича
@Mock
private lateinit var repository: Repository
@Rule
@JvmField
var toothPickRule = ToothPickRule(this, app)
85
TOOTHPICK
LIGHTSABER.CONCLUSION()
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A? 86
LIGHTSABER.CONCLUSION()
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A? 86
LIGHTSABER.CONCLUSION()
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
▸Брат по духу с Dagger
86
LIGHTSABER.CONCLUSION()
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
▸Брат по духу с Dagger
▸Нет боли с APT
86
LIGHTSABER.CONCLUSION()
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
▸Брат по духу с Dagger
▸Нет боли с APT
▸Вербозный
86
LIGHTSABER.CONCLUSION()
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
▸Брат по духу с Dagger
▸Нет боли с APT
▸Вербозный
▸Неудобный для тестов
86
LIGHTSABER.CONCLUSION()
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
▸Брат по духу с Dagger
▸Нет боли с APT
▸Вербозный
▸Неудобный для тестов
▸Нерелизная версия
86
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
KODEIN.CONCLUSION()
87
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
KODEIN.CONCLUSION()
87
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
KODEIN.CONCLUSION()
▸Действительно лёгкий
87
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
KODEIN.CONCLUSION()
▸Действительно лёгкий
▸Kotlin friendly
87
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
KODEIN.CONCLUSION()
▸Действительно лёгкий
▸Kotlin friendly
▸Runtime-проверка графа
87
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
KODEIN.CONCLUSION()
▸Действительно лёгкий
▸Kotlin friendly
▸Runtime-проверка графа
▸С тестированием уже
легче
87
TOOTHPICK.CONCLUSION()
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A? 88
TOOTHPICK.CONCLUSION()
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A? 88
TOOTHPICK.CONCLUSION()
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
▸Детальный Scope
88
TOOTHPICK.CONCLUSION()
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
▸Детальный Scope
▸Бро для тестов
88
TOOTHPICK.CONCLUSION()
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
▸Детальный Scope
▸Бро для тестов
▸Compile + Runtime-проверка
графа
88
TOOTHPICK.CONCLUSION()
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
▸Детальный Scope
▸Бро для тестов
▸Compile + Runtime-проверка
графа
▸Нельзя сказать, что они достигли
простоты по сравнению с Dagger
88
ЕСТЬ ЛИ ЖИЗНЬ БЕЗ DAGGER’A?
FINAL
89
Simplicity Scope Tests Perf
Lightsaber
Kodein
Toothpick
Dagger
СПАСИБО!
OMG! NOW I NEED A
KODEIN DOZE..
special thanks to @georgeci
Ligthsaber
Kodein
Tootpick
git.io/v7cw8
git.io/v7cwY
git.io/v7cwg

More Related Content

Recently uploaded

ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
Ирония безопасности
 
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdfСИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
Хроники кибер-безопасника
 
Cyberprint. Dark Pink Apt Group [RU].pdf
Cyberprint. Dark Pink Apt Group [RU].pdfCyberprint. Dark Pink Apt Group [RU].pdf
Cyberprint. Dark Pink Apt Group [RU].pdf
Хроники кибер-безопасника
 
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Ирония безопасности
 
CVE. The Fortra's GoAnywhere MFT [RU].pdf
CVE. The Fortra's GoAnywhere MFT [RU].pdfCVE. The Fortra's GoAnywhere MFT [RU].pdf
CVE. The Fortra's GoAnywhere MFT [RU].pdf
Хроники кибер-безопасника
 
2023 Q4. The Ransomware report. [RU].pdf
2023 Q4. The Ransomware report. [RU].pdf2023 Q4. The Ransomware report. [RU].pdf
2023 Q4. The Ransomware report. [RU].pdf
Хроники кибер-безопасника
 

Recently uploaded (9)

ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
ИСТОЧНИКИ ИННОВАЦИОННОСТИ КИТАЯ (ПО ВЕРСИИ DGAP) | The Sources of China’s Inn...
 
MS Navigating Incident Response [RU].pdf
MS Navigating Incident Response [RU].pdfMS Navigating Incident Response [RU].pdf
MS Navigating Incident Response [RU].pdf
 
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdfСИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
СИСТЕМА ОЦЕНКИ УЯЗВИМОСТЕЙ CVSS 4.0 / CVSS v4.0 [RU].pdf
 
Cyberprint. Dark Pink Apt Group [RU].pdf
Cyberprint. Dark Pink Apt Group [RU].pdfCyberprint. Dark Pink Apt Group [RU].pdf
Cyberprint. Dark Pink Apt Group [RU].pdf
 
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
Cyber Defense Doctrine Managing the Risk Full Applied Guide to Organizational...
 
Ransomware_Q3 2023. The report [RU].pdf
Ransomware_Q3 2023.  The report [RU].pdfRansomware_Q3 2023.  The report [RU].pdf
Ransomware_Q3 2023. The report [RU].pdf
 
Malware. DCRAT (DARK CRYSTAL RAT) [RU].pdf
Malware. DCRAT (DARK CRYSTAL RAT) [RU].pdfMalware. DCRAT (DARK CRYSTAL RAT) [RU].pdf
Malware. DCRAT (DARK CRYSTAL RAT) [RU].pdf
 
CVE. The Fortra's GoAnywhere MFT [RU].pdf
CVE. The Fortra's GoAnywhere MFT [RU].pdfCVE. The Fortra's GoAnywhere MFT [RU].pdf
CVE. The Fortra's GoAnywhere MFT [RU].pdf
 
2023 Q4. The Ransomware report. [RU].pdf
2023 Q4. The Ransomware report. [RU].pdf2023 Q4. The Ransomware report. [RU].pdf
2023 Q4. The Ransomware report. [RU].pdf
 

Featured

How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
ThinkNow
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
Kurio // The Social Media Age(ncy)
 

Featured (20)

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPT
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 

Есть ли жизнь без Dagger'a, Михаил Крестьянинов Avito