Владимир Тагаков. dagger2: dependency injection in android

52
{ Dagger2: dependency injection in Android Vladimir Tagakov

Upload: mailrugroup

Post on 18-Aug-2015

211 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Владимир Тагаков. Dagger2: dependency injection in Android

{

Dagger2: dependency injection in Android

Vladimir Tagakov

Page 2: Владимир Тагаков. Dagger2: dependency injection in Android

Hollywood Principle

Page 3: Владимир Тагаков. Dagger2: dependency injection in Android

Не звоните нам, мы сами вам перезвоним.

Hollywood Principle

Page 4: Владимир Тагаков. Dagger2: dependency injection in Android

Это паттерн проектирования, а не библиотека.

В каждом проекте используется DI

Dependency Injection

Page 5: Владимир Тагаков. Dagger2: dependency injection in Android

Tweeter Tiwtter API

Network Client

Dependency Injection

Page 6: Владимир Тагаков. Dagger2: dependency injection in Android

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

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

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

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

public class Tweeter { public void tweet(String tweet) { TwitterApi api = new TwitterApi();

api.postTweet("JakeWharton", tweet);}

}

Page 11: Владимир Тагаков. Dagger2: dependency injection in Android

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

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

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

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

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

Tweeter tweeter = new Tweeter("JakeWharton");tweeter.tweet("Hello!");

Page 17: Владимир Тагаков. Dagger2: dependency injection in Android

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

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

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

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

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

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

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

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

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

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

Tweeter Tiwtter API

Network Client

Dependency Injection

Page 28: Владимир Тагаков. Dagger2: dependency injection in Android

Twitter App• Timeline• Tweeter

Tiwtter API Network Client

Dependency Injection

Page 29: Владимир Тагаков. Dagger2: dependency injection in Android

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

Guice Dagger (v1)

Немного истории

Page 31: Владимир Тагаков. Dagger2: dependency injection in Android

Граф объектов проверяется в рантайме Большое количество рефлексии Медленная инициализация

Guice

Page 32: Владимир Тагаков. Dagger2: dependency injection in Android

Использование FQCN в качестве ключей при хранении элементов графа

Использование рефлексии

Dagger (v1)

Page 33: Владимир Тагаков. Dagger2: dependency injection in Android

Разработан Java Core Libraries Team Compile time анализ графа

зависимостей Отсутствие рефлексии Совместимость с ProGuard

Dagger v2

Page 34: Владимир Тагаков. Dagger2: dependency injection in Android

@Module + @Provides: для удовлетворения зависимтостей

@Inject: для запроса зависимостей @Component: соединяет все это вместе

Dagger API

Page 35: Владимир Тагаков. Dagger2: dependency injection in Android

Модули – классы аннотированные @Module, содержащие методы аннотированные @Provides

Удовлетворение зависимостей

Page 36: Владимир Тагаков. Dagger2: dependency injection in Android

public class NetworkModule { OkHttpClient provideOkHttpClient() { return

new OkHttpClient();}

TwitterApi provideTwitterApi(OkHttpClient client) {return new TwitterApi(client); }}

Page 37: Владимир Тагаков. Dagger2: dependency injection in Android

@Modulepublic class NetworkModule { @Provides

OkHttpClient provideOkHttpClient() { return new OkHttpClient();

}

@ProvidesTwitterApi provideTwitterApi(OkHttpClient client) {return new TwitterApi(client); }}

Page 38: Владимир Тагаков. Dagger2: dependency injection in Android

@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

Удовлетворение зависимостей

OkHttpClient NetworkModule#provideOkHttpClient

TwitterApi NetworkModule#provideTwitterApi

Page 40: Владимир Тагаков. Dagger2: dependency injection in Android

Удовлетворение зависимостей

OkHttpClient NetworkModule#provideOkHttpClient

TwitterApi NetworkModule#provideTwitterApi

Tweeter NetworkModule#provideTweeter

Timeline NetworkModule#provideTimeline

Page 41: Владимир Тагаков. Dagger2: dependency injection in Android

Injection в конструктор Injection в поле Injection в метод

Типы injection

Page 42: Владимир Тагаков. Dagger2: dependency injection in Android

@Inject на единственном конструкторе Параметры конструктора –

зависимости Зависимости можно хранить в

приватных переменных Неявно делает класс доступным для

последующего инжекта

Injection в конструктор

Page 43: Владимир Тагаков. Dagger2: dependency injection in Android

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

@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

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

@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

@Inject над каждой зависимостью Поля не могут быть private или final Объект ответственен за процесс

инжекта

Единственный способ инъектить зависимости в объекты созданием которых управляем не мы

Injection в поле

Page 48: Владимир Тагаков. Dagger2: dependency injection in Android

public class TwitterActivity extends Activity { @Inject Tweeter tweeter;

@Inject Timeline timeline; // ...}

Page 49: Владимир Тагаков. Dagger2: dependency injection in Android

Мост между модулями и получателями зависимостей

Инжектор

Components

Page 50: Владимир Тагаков. Dagger2: dependency injection in Android

@Singleton@Component(modules = { NetworkModule.class,TwitterModule.class,})public interface TwitterComponent {

Tweeter tweeter();void inject(TwitterActivity activity);

}

Page 51: Владимир Тагаков. Dagger2: dependency injection in Android

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

Linked.in/in/tagakov

Вопросы?