Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Toothpick - A fresh approach to DI
Search
Daniel Molinero Reguera
November 04, 2016
Programming
0
130
Toothpick - A fresh approach to DI
Presented at Mobile Era 2016, Andevcon SF 2016 and Andevcon Washington 2017
Daniel Molinero Reguera
November 04, 2016
Tweet
Share
More Decks by Daniel Molinero Reguera
See All by Daniel Molinero Reguera
TP3 & KTP: Simple, fast, and boilerplate-free DI for Kotlin
dlemures
0
65
Toothpick - A fresh approach to DI - Short Version
dlemures
0
69
Toothpick - A fresh approach to DI (Including Unit Testing)
dlemures
1
1.1k
Toothpick Bad Practices 🙅 and Nice Tricks 👌
dlemures
0
110
Dart & Henson - Better Android Intents
dlemures
1
230
Toothpick & Dependency Injection
dlemures
1
2.1k
Other Decks in Programming
See All in Programming
複雑なドメインに挑む.pdf
yukisakai1225
5
1.2k
Android 16 × Jetpack Composeで縦書きテキストエディタを作ろう / Vertical Text Editor with Compose on Android 16
cc4966
2
270
AI時代のUIはどこへ行く?
yusukebe
18
9.1k
テストカバレッジ100%を10年続けて得られた学びと品質
mottyzzz
2
610
AIと私たちの学習の変化を考える - Claude Codeの学習モードを例に
azukiazusa1
11
4.4k
パッケージ設計の黒魔術/Kyoto.go#63
lufia
3
440
Cache Me If You Can
ryunen344
2
4k
How Android Uses Data Structures Behind The Scenes
l2hyunwoo
0
480
250830 IaCの選定~AWS SAMのLambdaをECSに乗り換えたときの備忘録~
east_takumi
0
400
Navigating Dependency Injection with Metro
zacsweers
3
3.5k
JSONataを使ってみよう Step Functionsが楽しくなる実践テクニック #devio2025
dafujii
1
640
請來的 AI Agent 同事們在寫程式時,怎麼用 pytest 去除各種幻想與盲點
keitheis
0
130
Featured
See All Featured
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
6k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.9k
RailsConf 2023
tenderlove
30
1.2k
Typedesign – Prime Four
hannesfritz
42
2.8k
Documentation Writing (for coders)
carmenintech
74
5k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
930
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
15k
Embracing the Ebb and Flow
colly
87
4.8k
Building a Modern Day E-commerce SEO Strategy
aleyda
43
7.6k
Optimising Largest Contentful Paint
csswizardry
37
3.4k
Art, The Web, and Tiny UX
lynnandtonic
303
21k
Transcript
A FRESH APPROACH TO DI TOOTHPICK https://github.com/stephanenicolas/toothpick/
ABOUT US Senior Android Dev @ Groupon ~20 years of
Java coding OSS: Dart, TP, BoundBox, … STEPHANE NICOLAS DANIEL MOLINERO REGUERA Android Dev @ Groupon Turbulence Ninja OSS: Dart, TP. +stephane @D_Lemures
5IF"OESPJE5FBNJT)JSJOH jobs.groupon.com/careers/
THE TALK WHY DI ? WHY TOOTHPICK? TOOTHPICK FEATURES
ADVANCED FEATURES CONCLUSION SCOPE MODULES & BINDINGS SCOPE TREE SCOPE SINGLETONS MVP & STATE PRESERVATION MULTIPLE ACTIVITIES FLOWS
WHY DI ?
WHY DI ? DECOUPLE
WHY DI ? DECOUPLE USES
WHY DI ? DECOUPLE REUSE USES
WHY DI ? DECOUPLE REUSE USES USES USES
WHY DI ? DECOUPLE REUSE TEST USES USES USES
WHY DI ? DECOUPLE REUSE TEST USES USES USES MOCK
USES
WHY TOOTHPICK?
WHY TOOTHPICK? SIMPLER
WHY TOOTHPICK? SIMPLER BETTER TEST SUPPORT
WHY TOOTHPICK? SIMPLER BETTER TEST SUPPORT EVEN FASTER
TOOTHPICK FEATURES public class SmoothieMachine { @Inject IceMachine iceMachine;
public void doSmoothie() { iceMachine.makeIce(); } } @Singleton public class IceMachine { Foo foo; @Inject public IceMachine(Foo foo) { this.foo = foo; }
TOOTHPICK FEATURES public class SmoothieMachine { @Inject IceMachine iceMachine;
public void doSmoothie() { iceMachine.makeIce(); } } @Singleton public class IceMachine { Foo foo; @Inject public IceMachine(Foo foo) { this.foo = foo; } JSR 330 annotations→nothing new here
TOOTHPICK FEATURES SCOPE SCOPE
TOOTHPICK FEATURES SCOPE SCOPE MAKE INJECTIONS
TOOTHPICK FEATURES SCOPE SCOPE MAKE INJECTIONS public class MyApplication extends
Application { @Inject Machine machine; @Override protected void onCreate() { super.onCreate(); Scope appScope = Toothpick.openScope(this); appScope.installModules(…); Toothpick.inject(this, appScope); } }
TOOTHPICK FEATURES SCOPE, MODULES & BINDINGS SCOPE
TOOTHPICK FEATURES SCOPE, MODULES & BINDINGS SCOPE BINDINGS
TOOTHPICK FEATURES SCOPE, MODULES & BINDINGS SCOPE BINDINGS MODULES
TOOTHPICK FEATURES SCOPE, MODULES & BINDINGS SCOPE BINDINGS MODULES public
class MyApplication extends Application { @Inject Machine machine; @Override protected void onCreate() { super.onCreate(); Scope appScope = Toothpick.openScope(this); appScope.installModules(new Module() {{ bind(Machine.class).to(IceMachine.class); }}); Toothpick.inject(this, appScope); } }
TOOTHPICK FEATURES APPLICATION SCOPE ACTIVITY 1 SCOPE SCOPE TREE
TOOTHPICK FEATURES APPLICATION SCOPE SCOPE TREE
TOOTHPICK FEATURES APPLICATION SCOPE ACTIVITY 2 SCOPE SCOPE TREE
TOOTHPICK FEATURES APPLICATION SCOPE ACTIVITY 2 SCOPE SERVICE 1 SCOPE
SCOPE TREE
TOOTHPICK FEATURES APPLICATION SCOPE ACTIVITY 2 SCOPE SERVICE 1 SCOPE
FRAGMENT 1 SCOPE SCOPE TREE
TOOTHPICK FEATURES APPLICATION SCOPE ACTIVITY 2 SCOPE SERVICE 1 SCOPE
FRAGMENT 1 SCOPE FRAGMENT 2 SCOPE SCOPE TREE
TOOTHPICK FEATURES APPLICATION SCOPE ACTIVITY 2 SCOPE SERVICE 1 SCOPE
FRAGMENT 3 SCOPE FRAGMENT 1 SCOPE FRAGMENT 2 SCOPE SCOPE TREE
TOOTHPICK FEATURES public class LemonActivity extends Activity { @Inject
Machine machine; @Inject Context context; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Scope scope = Toothpick.openScopes(getApplication(), this); scope.installModules(…); Toothpick.inject(this, scope); } } SCOPE TREE
TOOTHPICK FEATURES public class LemonActivity extends Activity { @Inject
Machine machine; @Inject Context context; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Scope scope = Toothpick.openScopes(getApplication(), this); scope.installModules(…); Toothpick.inject(this, scope); } } SCOPE TREE APPLICATION SCOPE ACTIVITY SCOPE
TOOTHPICK FEATURES APPLICATION SCOPE ACTIVITY SCOPE SCOPE SINGLETONS
TOOTHPICK FEATURES APPLICATION SCOPE ACTIVITY SCOPE APP SINGLETONS SCOPE SINGLETONS
TOOTHPICK FEATURES APPLICATION SCOPE ACTIVITY SCOPE APP SINGLETONS ACTIVITY SINGLETONS
SCOPE SINGLETONS
TOOTHPICK FEATURES public class Module extends Module { public Module()
{ bind(Machine.class).toInstance(new Ice Machine()); } } SCOPE SINGLETONS SINGLETONS CAN BE DEFINED IN MODULES
TOOTHPICK FEATURES @Singleton public class IceMachine { } @ActivitySingleton public
class SmoothieMachine { } APPLICATION SCOPE ACTIVITY SCOPE SCOPE SINGLETONS OR USING ANNOTATIONS
ADVANCED TOOTHPICK FEATURES MVP & STATE PRESERVATION
ADVANCED TOOTHPICK FEATURES MVP & STATE PRESERVATION
ADVANCED TOOTHPICK FEATURES MVP & STATE PRESERVATION
APPLICATION SCOPE ADVANCED TOOTHPICK FEATURES MVP & STATE PRESERVATION ACTIVITY
SCOPE
APPLICATION SCOPE ADVANCED TOOTHPICK FEATURES MVP & STATE PRESERVATION ACTIVITY
SCOPE
APPLICATION SCOPE PRESENTER SCOPE ADVANCED TOOTHPICK FEATURES MVP & STATE
PRESERVATION ACTIVITY SCOPE
PRESENTER INSTANCE APPLICATION SCOPE PRESENTER SCOPE ADVANCED TOOTHPICK FEATURES MVP
& STATE PRESERVATION ACTIVITY SCOPE
PRESENTER INSTANCE APPLICATION SCOPE PRESENTER SCOPE ADVANCED TOOTHPICK FEATURES MVP
& STATE PRESERVATION
PRESENTER INSTANCE APPLICATION SCOPE PRESENTER SCOPE ADVANCED TOOTHPICK FEATURES MVP
& STATE PRESERVATION ACTIVITY SCOPE
ADVANCED TOOTHPICK FEATURES MVP & STATE PRESERVATION public class MyActivity
extends Activity { @Inject MyPresenter presenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Scope scope = openScopes(getApplication(), PresenterSingleton.class, this); Toothpick.inject(this, scope); } }
@PresenterSingleton public class MyPresenter { String dealId; int quantity; }
PRESENTER SCOPE MVP & STATE PRESERVATION ADVANCED TOOTHPICK FEATURES
ACTIVITY 1 ADVANCED TOOTHPICK FEATURES ACTIVITY 3 ACTIVITY 2 MULTI
ACTIVITY FLOWS
ACTIVITY 1 ADVANCED TOOTHPICK FEATURES ACTIVITY 3 ACTIVITY 2 MULTI
ACTIVITY FLOWS Purchase Flow
ACTIVITY 1 ADVANCED TOOTHPICK FEATURES ACTIVITY 3 ACTIVITY 2 MULTI
ACTIVITY FLOWS Purchase Flow
ACTIVITY 1 ADVANCED TOOTHPICK FEATURES ACTIVITY 3 ACTIVITY 2 MULTI
ACTIVITY FLOWS
ACTIVITY 1 ADVANCED TOOTHPICK FEATURES ACTIVITY 3 ACTIVITY 2 MULTI
ACTIVITY FLOWS
ACTIVITY 1 ADVANCED TOOTHPICK FEATURES ACTIVITY 3 ACTIVITY 2 MULTI
ACTIVITY FLOWS
ACTIVITY 1 ADVANCED TOOTHPICK FEATURES ACTIVITY 3 ACTIVITY 2 MULTI
ACTIVITY FLOWS
APPLICATION SCOPE ACTIVITY 1 SCOPE ADVANCED TOOTHPICK FEATURES FLOW SCOPE
MULTI ACTIVITY FLOWS
APPLICATION SCOPE ACTIVITY 1 SCOPE ADVANCED TOOTHPICK FEATURES FLOW SCOPE
MULTI ACTIVITY FLOWS
APPLICATION SCOPE ACTIVITY 1 SCOPE ADVANCED TOOTHPICK FEATURES FLOW SCOPE
ACTIVITY 2 SCOPE MULTI ACTIVITY FLOWS
APPLICATION SCOPE ACTIVITY 1 SCOPE ADVANCED TOOTHPICK FEATURES FLOW SCOPE
ACTIVITY 3 SCOPE ACTIVITY 2 SCOPE MULTI ACTIVITY FLOWS
APPLICATION SCOPE ADVANCED TOOTHPICK FEATURES FLOW SCOPE MULTI ACTIVITY FLOWS
APPLICATION SCOPE ADVANCED TOOTHPICK FEATURES MULTI ACTIVITY FLOWS
ADVANCED TOOTHPICK FEATURES MVP & STATE PRESERVATION public class MyActivity
extends Activity { @Inject ShoppingCart shoppingCart; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Scope scope = openScopes(getApplication(), FlowSingleton.class, this); Toothpick.inject(this, scope); } }
@FlowSingleton public class ShoppingCart { List<PurchaseItem> purchases… } FLOW SCOPE
MULTI ACTIVITY FLOWS ADVANCED TOOTHPICK FEATURES
CONCLUSION QUESTIONS ? COMMENTS ?
CONCLUSION QUESTIONS ? COMMENTS ?
A FRESH APPROACH TO DI TOOTHPICK https://github.com/stephanenicolas/toothpick/ +stephane @D_Lemures