Владимир Тагаков. Dagger2: dependency injection in Android
-
Upload
mailrugroup -
Category
Software
-
view
206 -
download
0
Transcript of Владимир Тагаков. Dagger2: dependency injection in Android
![Page 1: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/1.jpg)
{
Dagger2: dependency injection in Android
Vladimir Tagakov
![Page 2: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/2.jpg)
Hollywood Principle
![Page 3: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/3.jpg)
Не звоните нам, мы сами вам перезвоним.
Hollywood Principle
![Page 4: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/4.jpg)
Это паттерн проектирования, а не библиотека.
В каждом проекте используется DI
Dependency Injection
![Page 5: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/5.jpg)
Tweeter Tiwtter API
Network Client
Dependency Injection
![Page 6: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/6.jpg)
public class Tweeter { public void tweet(String tweet) { TwitterApi api = new TwitterApi();
api.postTweet("JakeWharton", tweet);}
}
public class TwitterApi {public void postTweet(String user, String tweet) {
OkHttpClient client = new OkHttpClient(); Request request = //...
client.newCall(request).execute(); }}
![Page 7: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/7.jpg)
public class TwitterApi {private final OkHttpClient client =
new OkHttpClient();
public void postTweet(String user, String tweet) { Request request = //... client.newCall(request).execute();
}}
![Page 8: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/8.jpg)
public class TwitterApi {private final OkHttpClient client =
new OkHttpClient();
public void postTweet(String user, String tweet) { Request request = //... client.newCall(request).execute();
}}
![Page 9: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/9.jpg)
public class TwitterApi {private final OkHttpClient client;public TwitterApi(OkHttpClient client) {
this.client = client;}
public void postTweet(String user, String tweet) { Request request = //... client.newCall(request).execute();
}}
![Page 10: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/10.jpg)
public class Tweeter { public void tweet(String tweet) { TwitterApi api = new TwitterApi();
api.postTweet("JakeWharton", tweet);}
}
![Page 11: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/11.jpg)
public class Tweeter { public void tweet(String tweet) { TwitterApi api = new TwitterApi(
new OkHttpClient() );api.postTweet("JakeWharton", tweet);
}}
![Page 12: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/12.jpg)
public class Tweeter { public void tweet(String tweet) { TwitterApi api = new TwitterApi(
new OkHttpClient() );api.postTweet("JakeWharton", tweet);
}}
![Page 13: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/13.jpg)
public class Tweeter { private final TwitterApi api = new TwitterApi(new OkHttpClient());
public void tweet(String tweet) {api.postTweet("JakeWharton", tweet);
}}
![Page 14: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/14.jpg)
public class Tweeter { private final TwitterApi api = new TwitterApi(new OkHttpClient());
public void tweet(String tweet) {api.postTweet("JakeWharton", tweet);
}}
![Page 15: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/15.jpg)
public class Tweeter { private final TwitterApi api = new TwitterApi(new OkHttpClient());
public Tweeter(String user) { this.user = user;}
public void tweet(String tweet) {api.postTweet(user, tweet);
}}
![Page 16: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/16.jpg)
Tweeter tweeter = new Tweeter("JakeWharton");tweeter.tweet("Hello!");
![Page 17: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/17.jpg)
Tweeter tweeter = new Tweeter("JakeWharton");tweeter.tweet("Hello!");
Timeline timeline = new Timeline("JakeWharton");timeline.loadMore(20);for (Tweet tweet : timeline.get()) {
System.out.println(tweet);}
![Page 18: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/18.jpg)
public class Timeline {private final List<Tweet> cache =
new ArrayList<>();private final TwitterApi api =
new TwitterApi(new OkHttpClient()); private final String user;
public Timeline(String user) { this.user = user; }
public List<Tweet> get() { /* ... */ } public void loadMore(int amount) { /* ... */ }}
![Page 19: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/19.jpg)
public class Timeline {private final List<Tweet> cache =
new ArrayList<>();private final TwitterApi api;
private final String user;
public Timeline(TwitterApi api, String user) {this.user = user;
this.api = api; }
public List<Tweet> get() { /* ... */ } public void loadMore(int amount) { /* ... */ }}
![Page 20: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/20.jpg)
public class Timeline {private final List<Tweet> cache =
new ArrayList<>();private final TwitterApi api;
private final String user;
public Timeline(TwitterApi api, String user) {this.user = user;
this.api = api; }
public List<Tweet> get() { /* ... */ } public void loadMore(int amount) { /* ... */ }}
![Page 21: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/21.jpg)
public class Tweeter { private final TwitterApi api = new TwitterApi(new OkHttpClient());
public Tweeter(String user) { this.user = user;}
public void tweet(String tweet) {api.postTweet(user, tweet);
}}
![Page 22: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/22.jpg)
public class Tweeter { private final TwitterApi api;
public Tweeter(TwitterApi api, String user) {this.user = user;
this.api = api; }
public void tweet(String tweet) {api.postTweet(user, tweet);
}}
![Page 23: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/23.jpg)
public class Tweeter { private final TwitterApi api;
public Tweeter(TwitterApi api, String user) {this.user = user;
this.api = api; }
public void tweet(String tweet) {api.postTweet(user, tweet);
}}
![Page 24: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/24.jpg)
Tweeter tweeter = new Tweeter("JakeWharton");tweeter.tweet("Hello!");
Timeline timeline = new Timeline("JakeWharton");timeline.loadMore(20);for (Tweet tweet : timeline.get()) {
System.out.println(tweet);}
![Page 25: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/25.jpg)
OkHttpClient client = new OkHttpClient();TwitterApi api = new TwitterApi(client);String user = "Jake Wharton"; Tweeter tweeter = new Tweeter(api, user);tweeter.tweet("Hello!"); Timeline timeline = new Timeline(api, user);timeline.loadMore(20);for (Tweet tweet : timeline.get()) {
System.out.println(tweet);}
![Page 26: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/26.jpg)
OkHttpClient client = new OkHttpClient();TwitterApi api = new TwitterApi(client);String user = "Jake Wharton"; Tweeter tweeter = new Tweeter(api, user);tweeter.tweet("Hello!"); Timeline timeline = new Timeline(api, user);timeline.loadMore(20);for (Tweet tweet : timeline.get()) {System.out.println(tweet);}
![Page 27: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/27.jpg)
Tweeter Tiwtter API
Network Client
Dependency Injection
![Page 28: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/28.jpg)
Twitter App• Timeline• Tweeter
Tiwtter API Network Client
Dependency Injection
![Page 29: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/29.jpg)
OkHttpClient client = new OkHttpClient();TwitterApi api = new TwitterApi(client);String user = "Jake Wharton"; Tweeter tweeter = new Tweeter(api, user);tweeter.tweet("Hello!"); Timeline timeline = new Timeline(api, user);timeline.loadMore(20);for (Tweet tweet : timeline.get()) {System.out.println(tweet);}
Как избежать этого?
![Page 30: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/30.jpg)
Guice Dagger (v1)
Немного истории
![Page 31: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/31.jpg)
Граф объектов проверяется в рантайме Большое количество рефлексии Медленная инициализация
Guice
![Page 32: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/32.jpg)
Использование FQCN в качестве ключей при хранении элементов графа
Использование рефлексии
Dagger (v1)
![Page 33: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/33.jpg)
Разработан Java Core Libraries Team Compile time анализ графа
зависимостей Отсутствие рефлексии Совместимость с ProGuard
Dagger v2
![Page 34: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/34.jpg)
@Module + @Provides: для удовлетворения зависимтостей
@Inject: для запроса зависимостей @Component: соединяет все это вместе
Dagger API
![Page 35: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/35.jpg)
Модули – классы аннотированные @Module, содержащие методы аннотированные @Provides
Удовлетворение зависимостей
![Page 36: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/36.jpg)
public class NetworkModule { OkHttpClient provideOkHttpClient() { return
new OkHttpClient();}
TwitterApi provideTwitterApi(OkHttpClient client) {return new TwitterApi(client); }}
![Page 37: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/37.jpg)
@Modulepublic class NetworkModule { @Provides
OkHttpClient provideOkHttpClient() { return new OkHttpClient();
}
@ProvidesTwitterApi provideTwitterApi(OkHttpClient client) {return new TwitterApi(client); }}
![Page 38: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/38.jpg)
@Modulepublic class NetworkModule { @Provides @Singleton OkHttpClient provideOkHttpClient() { return new OkHttpClient();
}
@Provides @SingletonTwitterApi provideTwitterApi(OkHttpClient client) {return new TwitterApi(client); }}
![Page 39: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/39.jpg)
Удовлетворение зависимостей
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
![Page 40: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/40.jpg)
Удовлетворение зависимостей
OkHttpClient NetworkModule#provideOkHttpClient
TwitterApi NetworkModule#provideTwitterApi
Tweeter NetworkModule#provideTweeter
Timeline NetworkModule#provideTimeline
![Page 41: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/41.jpg)
Injection в конструктор Injection в поле Injection в метод
Типы injection
![Page 42: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/42.jpg)
@Inject на единственном конструкторе Параметры конструктора –
зависимости Зависимости можно хранить в
приватных переменных Неявно делает класс доступным для
последующего инжекта
Injection в конструктор
![Page 43: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/43.jpg)
public class TwitterApplication { private final Tweeter tweeter; private final Timeline timeline;
@Inject public TwitterApplication(Tweeter tweeter, Timeline timeline) {
this.tweeter = tweeter; this.timeline = timeline;
} // ... }
![Page 44: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/44.jpg)
@Modulepublic class NetworkModule { @Provides @Singleton OkHttpClient provideOkHttpClient() { return new OkHttpClient();
}
@Provides @SingletonTwitterApi provideTwitterApi(OkHttpClient client) {return new TwitterApi(client); }}
![Page 45: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/45.jpg)
public class TwitterApi {private final OkHttpClient client;@Injectpublic TwitterApi(OkHttpClient client) {
this.client = client;}
public void postTweet(String user, String tweet) { Request request = //... client.newCall(request).execute();
}}
![Page 46: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/46.jpg)
@Singleton public class TwitterApi {
private final OkHttpClient client;@Injectpublic TwitterApi(OkHttpClient client) {
this.client = client;}
public void postTweet(String user, String tweet) { Request request = //... client.newCall(request).execute();
}}
![Page 47: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/47.jpg)
@Inject над каждой зависимостью Поля не могут быть private или final Объект ответственен за процесс
инжекта
Единственный способ инъектить зависимости в объекты созданием которых управляем не мы
Injection в поле
![Page 48: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/48.jpg)
public class TwitterActivity extends Activity { @Inject Tweeter tweeter;
@Inject Timeline timeline; // ...}
![Page 49: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/49.jpg)
Мост между модулями и получателями зависимостей
Инжектор
Components
![Page 50: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/50.jpg)
@Singleton@Component(modules = { NetworkModule.class,TwitterModule.class,})public interface TwitterComponent {
Tweeter tweeter();void inject(TwitterActivity activity);
}
![Page 51: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/51.jpg)
public class TwitterActivity extends Activity { @Inject Tweeter tweeter;
@Inject Timeline timeline; public void onCreate(Bundle savedInstanceState) {
Dagger_TwitterComponent.builder()
.build().inject(this);}
// ...}
![Page 52: Владимир Тагаков. Dagger2: dependency injection in Android](https://reader035.fdocuments.us/reader035/viewer/2022062308/55d30803bb61eb5c5a8b480c/html5/thumbnails/52.jpg)
Linked.in/in/tagakov
Вопросы?