I know there are many similar questions but I still haven't been able to find a solution for my problem and at this stage, I'm out of ideas. I have the following setup:
This is how the code looks:
ApplicationModule.java
@Module
public class ApplicationModule {
private Application mApp;
public ApplicationModule(Application app) {
mApp = app;
}
@Provides
@Singleton
public Application provideApplication() {
return mApp;
}
@Provides
@Singleton
Context provideApplicationContext() {
return mApp.getApplicationContext();
}
}
ApplicationComponent.java
@Singleton
@Component(modules = {ApplicationModule.class})
public interface ApplicationComponent {
Application application();
Context getContext();
}
NetModule.java
@Module
public class NetModule {
String mBaseUrl;
public NetModule(String baseUrl) {
this.mBaseUrl = baseUrl;
}
@Provides
@Singleton
SharedPreferences providesSharedPreferences(Application application) {
return PreferenceManager.getDefaultSharedPreferences(application);
}
@Provides
@Singleton
Cache provideOkHttpCache(Application application) {
int cacheSize = 10 * 1024 * 1024; // 10 MiB
return new Cache(application.getCacheDir(), cacheSize);
}
@Provides
@Singleton
OkHttpClient provideOkHttpClient(Cache cache) {
OkHttpClient client = new OkHttpClient();
client.setCache(cache);
return client;
}
@Provides
@Singleton
Retrofit provideRetrofit(OkHttpClient okHttpClient) {
return new Retrofit.Builder()
.addConverterFactory(JacksonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl(mBaseUrl)
.client(okHttpClient)
.build();
}
@Provides
@Singleton
PlaceRequests providePlaceRequests(Retrofit retrofit) {
return retrofit.create(PlaceRequests.class);
}
}
NetComponent.java
@Singleton
@Component(
dependencies = {ApplicationModule.class},
modules = {NetModule.class}
)
public interface NetComponent {
Application application();
PlaceRequests getPlaceRequests();
}
CityModule.java
@Module
public class CityModule {
private CityMvp.View view;
public CityModule(CityMvp.View view) {
this.view = view;
}
@Provides
public CityMvp.View provideView() {
return view;
}
@Provides
public CityMvp.Interactor provideInteractor(PlaceRequests placeRequests) {
return new CityInteractor(placeRequests);
}
@Provides
public CityPresenter providePresenter(CityMvp.View cityView, CityMvp.Interactor interactor) {
return new CityPresenter(cityView, interactor);
}
}
CityComponent.java
@PerFragment
@Component(
dependencies = {NetModule.class},
modules = {CityModule.class}
)
public interface CityComponent {
void inject(CityFragment cityFragment);
}
CityInteractor.java (the one that is not able to inject cause the PlaceRequests dependency)
public class CityInteractor implements CityMvp.Interactor {
private PlaceRequests placeRequests;
public CityInteractor(PlaceRequests placeRequests) {
this.placeRequests = placeRequests;
}
@Override
public void getPlaceDetails(String placeId, String key, Subscriber<PlaceDetails> subscriber) {
Observable<PlaceDetails> observable = placeRequests.getPlaceDetails(placeId, key);
observable.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(subscriber);
}
}
Finally, the error trace:
: error: com.blabla.blabla.webapi.place.PlaceRequests cannot be provided without an @Provides-annotated method.
void inject(CityFragment cityFragment);
^
com.blabla.blabla.screens.city.CityFragment.presenter
[injected field of type: com.blabla.blabla.screens.city.CityPresenter presenter]
com.blabla.blabla.di.modules.CityModule.providePresenter(com.blabla.blabla.screens.city.CityMvp.View cityView, com.blabla.blabla.screens.city.CityMvp.Interactor interactor)
[parameter: com.blabla.blabla.screens.city.CityMvp.Interactor interactor]
com.blabla.blabla.di.modules.CityModule.provideInteractor(com.blabla.blabla.webapi.place.PlaceRequests placeRequests)
[parameter: com.blabla.blabla.webapi.place.PlaceRequests placeRequests]
3 errors
:app:compileDebugJavaWithJavac FAILED
FAILURE: Build failed with an exception.
From what I understand, I'm exposing PlaceRequests object in NetComponent.java, and NetModule.java is a dependency of CityComponent. How come I'm not able to get PlaceRequests dependency from CityComponent? What am I missing? Thanks!
Component dependencies specified through @Component(dependencies={...})
shouldn't be Modules, as you have them. They should be types (typically Components) that make dependencies available through zero-arg methods known as provision methods.
Switch your dependencies to the components instead of modules.
If it helps, you might want to change how you think about Components, Modules, and component dependencies. You can think of Dagger as creating an object graph where Modules define the inputs or bindings of the graph and Components define the outputs or consumers of the graph. This leaves component dependencies to be types or components included or imported from another external source, which might include a different Dagger-created Component, but probably wouldn't include a Module--instead of a dependency on the Module you'd depend on the Component that consumes the module.
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