Я играю с 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]
Итак, мои вопросы:
SecondActivity
независимо от компонента, используемого для вызова inject
метод, это правильный способ сделать это.А... Я разделяю твою боль. Вы не можете вводить два компонента в одно действие. По крайней мере, я не мог найти, как это сделать!:)
Это было логично и для меня, и я столкнулся с такими же проблемами.
Вы можете решить эту проблему с помощью подхода 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);
}
Я нашел второе в качестве самого чистого решения.
Если у кого-нибудь есть другой совет, я готов попробовать!