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
Dagger2: Практический ликбез по работе с кинжалами
Search
Dmitry Polishuk
September 25, 2015
Programming
0
150
Dagger2: Практический ликбез по работе с кинжалами
Краткое введение по работе с Dagger2
Dmitry Polishuk
September 25, 2015
Tweet
Share
Other Decks in Programming
See All in Programming
高速開発のためのコード整理術
sutetotanuki
1
380
Honoを使ったリモートMCPサーバでAIツールとの連携を加速させる!
tosuri13
1
170
dchart: charts from deck markup
ajstarks
3
990
今から始めるClaude Code超入門
448jp
7
8.3k
副作用をどこに置くか問題:オブジェクト指向で整理する設計判断ツリー
koxya
1
590
カスタマーサクセス業務を変革したヘルススコアの実現と学び
_hummer0724
0
610
OCaml 5でモダンな並列プログラミングを Enjoyしよう!
haochenx
0
120
IFSによる形状設計/デモシーンの魅力 @ 慶應大学SFC
gam0022
1
290
組織で育むオブザーバビリティ
ryota_hnk
0
170
AIフル活用時代だからこそ学んでおきたい働き方の心得
shinoyu
0
130
Automatic Grammar Agreementと Markdown Extended Attributes について
kishikawakatsumi
0
180
Vibe codingでおすすめの言語と開発手法
uyuki234
0
220
Featured
See All Featured
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
0
190
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
0
3.4k
Producing Creativity
orderedlist
PRO
348
40k
[SF Ruby Conf 2025] Rails X
palkan
0
740
Mobile First: as difficult as doing things right
swwweet
225
10k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Principles of Awesome APIs and How to Build Them.
keavy
128
17k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
47
How to train your dragon (web standard)
notwaldorf
97
6.5k
Ruling the World: When Life Gets Gamed
codingconduct
0
140
From π to Pie charts
rasagy
0
120
Transcript
Dagger2: Практический ликбез по работе с кинжалами Дмитрий Полищук
Что такое сильно связный код?
Начнем издалека public class NetworkClient { } private static final
class NetworkClientHolder { static NetworkClient INSTANCE = new NetworkClient(); } public FutureTask<Response> execute(Request request) { ... } public NetworkClient() { this.client = new OkHttpClient(); } public static NetworkClient getInstance() { return NetworkClientHolder.INSTANCE; }
Продолжаем public class MyFragment extends Fragment { } @Override public
void onResume() { super.onResume(); updateFeed(); } private void updateFeed() { NetworkClient client = NetworkClient.getInstance(); FutureTask<Response> response = client.execute(request); ... }
К. Киммель “Снежный ком” Разработчики Менеджеры Тестировщики
〉 Весь проект начинает зависеть именно от этих классов-синглтонов 〉
Проект становится монолитным 〉 И как следствие - его очень тяжело поддерживать Проблемы синглтонов:
НЕ ТВОЙ БРО MyActivity NetworkClient OkHttpClient MyActivity OkHttpClient NetworkClient ТВОЙ
БРО
Внедрение зависимости через конструктор public class NetworkClient { } public
FutureTask<Response> execute(Request request) { ... } public NetworkClient(Client client) { this.client = client; }
Внедрение зависимости через конструктор public class MyFragment extends Fragment {
@Override public void onResume() { super.onResume(); updateFeed(); } } private void updateFeed() { NetworkClient client = NetworkClient.getInstance(); FutureTask<Response> response = client.execute(request); ... } private void updateFeed() { Client client = new OkHttpClient(); NetworkClient client = new NetworkClient(client); FutureTask<Response> response = client.execute(request); ... }
Внедрение зависимостей c Dagger2
Создаем модуль @Module public class NetworkModule { } @Provides @Singleton
Client provideOkHttpClient() { return new OkHttpClient(); }
Модуль -‐ это конфиг
NetworkClient и constructor injection public class NetworkClient { } public
FutureTask<Response> execute(Request request) { ... } public NetworkClient(Client client) { this.client = client; } @Inject @Singleton private final Client client;
NetworkClient и setter injection public class NetworkClient { } public
FutureTask<Response> execute(Request request) { ... } public void setClient(Client client) { this.client = client; } @Inject @Singleton public NetworkClient() { } @Inject private final Client client; private Client client;
Внедрение NetworkClient с Dagger2 public class MyFragment extends Fragment {
} private void updateFeed() { Client client = new OkHttpClient(); NetworkClient client = new NetworkClient(client); FutureTask<Response> response = client.execute(request); ... } private void updateFeed() { FutureTask<Response> response = client.execute(request); ... } @Inject NetworkClient client; @Override public void onActivityCreated(Bundle state) { super.onActivityCreated(state); getComponent().inject(this); } Injection в поле
Создаем @Component @Component(modules = { NetworkModule.class }) public interface AppComponent
{ } @Singleton
Как это работает? @Generated("dagger.internal.codegen.ComponentProcessor") public final class MyFragment_MembersInjector implements MembersInjector<MyFragment>
{ private final MembersInjector<BaseFragment> supertypeInjector; private final Provider<NetworkClient> clientProvider; public MyFragment_MembersInjector(MembersInjector<BaseFragment> supertypeInjector, Provider<NetworkClient> clientProvider) { assert supertypeInjector != null; this.supertypeInjector = supertypeInjector; assert clientProvider != null; this.clientProvider = clientProvider; } @Override public void injectMembers(MyFragment instance) { if (instance == null) { throw new NullPointerException("Cannot inject members into a null reference"); } supertypeInjector.injectMembers(instance); instance.client = clientProvider.get(); } public static MembersInjector<MyFragment> create(MembersInjector<BaseFragment> supertypeInjector, Provider<NetworkClient> cli return new MyFragment_MembersInjector(supertypeInjector, clientProvider); } }
Как это работает? AppComponent component = DaggerAppComponent .builder() .networkModule(new NetworkModule())
.build(); component.inject(this);
@Component vs @Subcomponent @PerActivity @Subcomponent(modules = ActivityModule.class) public interface ActivitySubcomponent
{ } @Component(modules = { NetworkModule.class }) public interface AppComponent { ActivitySubcomponent plus(ActivityModule module); } Определяем @Subcomponent Добавляем plus()
@Qualifier @Module public class NetworkModule { @Provides @Singleton NetworkClient taxiClient(Client
client) { return new NetworkClient(client, "https://taxi.yandex.ru/api"); } @Provides @Singleton NetworkClient mapsClient(Client client) { return new NetworkClient(client, "https://maps.yandex.ru/api"); } } @Named("taxi") @Named("maps")
@Qualifier @Inject @Named("taxi") NetworkClient taxiClient; @Inject @Named("maps") NetworkClient mapsClient;
Dagger IntelliJ Plugin https://github.com/square/dagger-intellij-plugin
В чем прикол? 〉Сгенерированный код как будто бы это было
написано человеком 〉Обфускация через Proguard без единой настройки 〉Полное отсутствие рефлексии
Ресурсы 〉Dagger1: http://square.github.io/dagger/ 〉Dagger2: http://google.github.io/dagger 〉Пример миграции (U2020 на Dagger2):
https://clck.ru/9aSsV 〉Пример про тестирование: https://clck.ru/9aVu4 〉DAGGER 2 - A New Type of dependency injection: http://www.youtube.com/watch?v=oK_XtfXPkqw
Спасибо за внимание! Дмитрий Полищук @dpolishuk deepol@yandex-‐team.ru