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
組織で育むオブザーバビリティ
ryota_hnk
0
180
副作用をどこに置くか問題:オブジェクト指向で整理する設計判断ツリー
koxya
1
620
AI時代の認知負荷との向き合い方
optfit
0
170
MDN Web Docs に日本語翻訳でコントリビュート
ohmori_yusuke
0
660
360° Signals in Angular: Signal Forms with SignalStore & Resources @ngLondon 01/2026
manfredsteyer
PRO
0
140
CSC307 Lecture 02
javiergs
PRO
1
780
React 19でつくる「気持ちいいUI」- 楽観的UIのすすめ
himorishige
11
7.5k
CSC307 Lecture 07
javiergs
PRO
1
560
MUSUBIXとは
nahisaho
0
140
なるべく楽してバックエンドに型をつけたい!(楽とは言ってない)
hibiki_cube
0
140
Fluid Templating in TYPO3 14
s2b
0
130
Honoを使ったリモートMCPサーバでAIツールとの連携を加速させる!
tosuri13
1
180
Featured
See All Featured
From π to Pie charts
rasagy
0
130
Chasing Engaging Ingredients in Design
codingconduct
0
120
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
110
Embracing the Ebb and Flow
colly
88
5k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
86
Reality Check: Gamification 10 Years Later
codingconduct
0
2k
Raft: Consensus for Rubyists
vanstee
141
7.3k
Building the Perfect Custom Keyboard
takai
2
690
Bash Introduction
62gerente
615
210k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
470
Typedesign – Prime Four
hannesfritz
42
3k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
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