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.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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With