Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dagger2: Практический ликбез по работе с кинжалами

Dagger2: Практический ликбез по работе с кинжалами

Краткое введение по работе с Dagger2

Dmitry Polishuk

September 25, 2015
Tweet

Other Decks in Programming

Transcript

  1. Начнем издалека 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; }
  2. Продолжаем 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); ... }
  3. 〉 Весь проект начинает зависеть именно от этих классов-синглтонов 〉

    Проект становится монолитным 〉 И как следствие - его очень тяжело поддерживать Проблемы синглтонов:
  4. Внедрение зависимости через конструктор public class NetworkClient { } public

    FutureTask<Response> execute(Request request) { ... } public NetworkClient(Client client) { this.client = client; }
  5. Внедрение зависимости через конструктор 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); ... }
  6. Создаем модуль @Module public class NetworkModule { } @Provides @Singleton

    Client provideOkHttpClient() { return new OkHttpClient(); }
  7. 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;
  8. 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;
  9. Внедрение 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  в  поле
  10. Как это работает? @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); } }
  11. @Component vs @Subcomponent @PerActivity @Subcomponent(modules = ActivityModule.class) public interface ActivitySubcomponent

    { } @Component(modules = { NetworkModule.class }) public interface AppComponent { ActivitySubcomponent plus(ActivityModule module); } Определяем  @Subcomponent Добавляем  plus()
  12. @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")
  13. В чем прикол? 〉Сгенерированный код как будто бы это было

    написано человеком 〉Обфускация через Proguard без единой настройки 〉Полное отсутствие рефлексии
  14. Ресурсы 〉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