Зависимости от двух компонентов в одной деятельности

1

Я играю с Dagger-2, чтобы понять, как интегрировать его в наше существующее приложение, и я сталкиваюсь с тем, что я не могу понять, или я ошибаюсь.

Моя ситуация:

3 API без какого-либо аннотированного конструктора (каждый в своем собственном файле)

public class DbApi {
   public void doSomething(String username, String password) {
   }
}

public class RestApi {
    public void doSomething(String username, String password) {
    }
}

public class SocketApi {
    public void doSomething(String username, String password) {
    }
}

3 Модули (каждый в своем собственном файле)

@Module
public class DbModule {
    @Provides
    @Singleton
    public DbApi getDbApi(){
        return new DbApi();
    }
}

@Module
public class RestModule {
    @Provides
    @Singleton
    public RestApi getRestApi(){
        return new RestApi();
    }
}

@Module
public class SocketModule {
    @Provides
    @Singleton
    public SocketApi getSocketApi(){
        return new SocketApi();
    }
}

2 Компоненты (каждый в своем собственном файле)

@Singleton
@Component(modules = {DbModule.class})
public interface DbComponent {
   void inject(SecondActivity activity);
}

@Singleton
@Component(modules = {RestModule.class, SocketModule.class})
public interface NetComponent {
   void inject(MainActivity activity);
}

Я инициализирую эти два компонента в свой Aplication

public class MyApplication extends Application {

DbComponent dBComponent;
NetComponent netComponent;

@Override
public void onCreate() {
    super.onCreate();
    dBComponent = DaggerDbComponent.builder().build();
    netComponent = DaggerNetComponent.builder().build();
}

public NetComponent getNetComponent() {
    return netComponent;
}

public DbComponent getdBComponent() {
    return dBComponent;
}
}

При всем этом я использую NetComponent в одно действие, а DbCompoment - на второй.

В первую операцию

public class MainActivity extends AppCompatActivity {

@Inject RestApi restApi;
@Inject SocketApi socketApi;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //...
    ((MyApplication) getApplication()).getNetComponent().inject(this);
    //...
}
}

и во второй

public class SecondActivity extends AppCompatActivity {

@Inject DbApi dbApi;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //...
    ((MyApplication) getApplication()).getdBComponent().inject(this);
    //...
}
}

До сих пор все работает отлично, и я получил свои вещи, вложенные в каждую деятельность. Но затем я понял, что RestApi и SocketApi также необходимы для SecondActity, поэтому я попытался ввести их в действие, и здесь у меня есть сомнения и проблемы.

Я изменяю свой NetComponent, чтобы добавить следующую строку

void inject(SecondActivity activity);

И я изменяю свой SecondActivity

public class SecondActivity extends AppCompatActivity {

@Inject DbApi dbApi;
@Inject RestApi restApi;
@Inject SocketApi socketApi;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //...
    ((MyApplication) getApplication()).getdBComponent().inject(this);
    ((MyApplication) getApplication()).getNetComponent().inject(this);
    //...
}
}

После этих модификаций, компилирующих мой проект, я имею следующую ошибку

Ошибка: (15, 10) error: com.example.guillaume.testdagger.RestApi не может быть предоставлен без конструктора @Inject или из метода @Provides- или @Produces-annotated.   com.example.guillaume.testdagger.SecondActivity.restApi   [введенное поле типа: com.example.guillaume.testdagger.RestApi restApi]

Ошибка: (16, 10) error: com.example.guillaume.testdagger.DbApi не может быть предоставлен без конструктора @Inject или из метода @Provides- или @Produces-annotated. com.example.guillaume.testdagger.SecondActivity.dbApi [введенное поле типа: com.example.guillaume.testdagger.DbApi dbApi]

Итак, мои вопросы:

  • Откуда эта ошибка?
  • Как я могу использовать несколько компонентов для ввода полей в одно действие.
  • Я делаю это неправильно и что будет лучшим способом организовать компоненты/модули, чтобы иметь возможность повторно использовать один компонент в активности, уже содержащей другой модуль.
  • Я могу исправить ошибку, добавив и очистив публичный конструктор, аннотированный с помощью @Inject, в мои классы api, но при этом я сказал, что все мои поля будут введены в SecondActivity независимо от компонента, используемого для вызова inject метод, это правильный способ сделать это.
Теги:
dagger-2

1 ответ

3
Лучший ответ

А... Я разделяю твою боль. Вы не можете вводить два компонента в одно действие. По крайней мере, я не мог найти, как это сделать!:)

Это было логично и для меня, и я столкнулся с такими же проблемами.

Вы можете решить эту проблему с помощью подхода 2:

  • Используйте один большой компонент для всех инъекций (я действительно снова это делаю)
  • Создайте один компонент для каждого действия/места, в которое вы хотите что-то ввести.

Итак, вместо

@Singleton
@Component(modules = {RestModule.class, SocketModule.class})
public interface NetComponent {
   void inject(MainActivity activity);
}

попробуйте

@Singleton
@Component(modules = {RestModule.class, SocketModule.class, DbModule.class})
public interface SecondActivityComponent {
   void inject(SecondActivity activity);
}

Я нашел второе в качестве самого чистого решения.

Если у кого-нибудь есть другой совет, я готов попробовать!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню