Reputation: 4228
I'm playing with Dagger-2 to figure how to integrate it in our existing application and I'm facing something which I can't understand or I'm doing wrong.
My situation :
3 API without any annotated constructor ( each one in its own file )
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 Modules ( each one in its own file )
@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 Components ( each one in its own file )
@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);
}
I initialize the two components into my 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;
}
}
With all this defined I use the NetComponent into one activity and the DbCompoment into a second one.
Into the first activity
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);
//...
}
}
and into the second
public class SecondActivity extends AppCompatActivity {
@Inject DbApi dbApi;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...
((MyApplication) getApplication()).getdBComponent().inject(this);
//...
}
}
Up to here everything works fine and I got my stuff injected properlty in each activity.
But then I have realised that RestApi
and SocketApi
were also required into the SecondActity so I tried to inject them into the activity and here I have doubts and issues.
I modify my NetComponent
to add the following line
void inject(SecondActivity activity);
And I modify my 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);
//...
}
}
After those modifications compiling my project I have the following error
Error:(15, 10) error: com.example.guillaume.testdagger.RestApi cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method. com.example.guillaume.testdagger.SecondActivity.restApi [injected field of type: com.example.guillaume.testdagger.RestApi restApi]
Error:(16, 10) error: com.example.guillaume.testdagger.DbApi cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method. com.example.guillaume.testdagger.SecondActivity.dbApi [injected field of type: com.example.guillaume.testdagger.DbApi dbApi]
So my questions are :
SecondActivity
regardless of the component used to invoke the inject
method, is it the right way to do this.Upvotes: 7
Views: 2111
Reputation: 3706
Ah...I share your pain. You can't inject two components into same Activity. At least I was not able to find how! :)
That was logical for me to try, as well, and I faced same problems.
You can resolve it with 2 approach:
So, instead of
@Singleton
@Component(modules = {RestModule.class, SocketModule.class})
public interface NetComponent {
void inject(MainActivity activity);
}
try with
@Singleton
@Component(modules = {RestModule.class, SocketModule.class, DbModule.class})
public interface SecondActivityComponent {
void inject(SecondActivity activity);
}
I found second one as cleanest solution.
If anybody has some other advice, I am ready to try it!
Upvotes: 10