I use "AppComponent" which has ActivityBuilderModule and ViewModelBuilderModule and SubComponent "NetworkComponent" which has NetworkModule which provide InterfaceRequest and I inject InterfaceRequest in Repository and inject Repository in ViewModel and the ViewModel is injected in Activity but I got this error:
[Dagger/MissingBinding] InterfaceRequests cannot be provided without an @Provides-annotated method.
public interface AppComponent {
A binding with matching key exists in component: NetworkComponent
InterfaceRequests is injected at
ForYouRepository.interfaceRequests
ForYouRepositoryis injected at
NewsViewModel(newsRepository)
NewsViewModel is injected at
ViewModelBuilderModule.bindNewsViewModel(newsViewModel)
java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> is injected at
ViewModelFactory(creators)
tech.gplanet.shopx.di.ViewModelFactory is injected at
tech.gplanet.shopx.ui.activities.NewsActivity.viewModelFactory
tech.gplanet.shopx.ui.activities.NewsActivity
AppComponent:
@Singleton
@Component(modules = { AndroidInjectionModule.class, ActivityBuilderModule.class, ViewModelBuilderModule.class})
public interface AppComponent {
void inject(MyApplication appClass);
@Component.Builder
interface Builder {
@BindsInstance
AppComponent.Builder context(Context context);
AppComponent build();
}
NetworkComponent.Builder getNetworkComponentBuilder();
}
Network Component:
@Subcomponent(modules = {NetworkModule.class})
public interface NetworkComponent {
void inject(RegisterationActivity registerationActivity);
void inject(AuthenticationRepository repository);
void inject(ForYouRepository repository);
@Subcomponent.Builder
interface Builder {
@BindsInstance
Builder customDeserializers(@Named("custom_deserializers") GeneralCustomDeserializerInterface[] deserializers);
@BindsInstance
@Nullable
Builder baseUrl(@Named("base_url") String baseUrl);
NetworkComponent build();
}
}
Repository code:
@Inject
public InterfaceRequests interfaceRequests;
@Inject
public ForYouRepository(Context context) {
NetworkComponent networkComponent = ((MyApplication)((Activity) context).getApplication()).getAppComponent()
.getNetworkComponentBuilder()
.baseUrl(Constants.BASE_URL)
.customDeserializers(new GeneralCustomDeserializerInterface[]{})
.build();
networkComponent.inject(this);
}
Network Module:
@Provides
public Gson provideGsonBuilder(@Named("custom_deserializers") GeneralCustomDeserializerInterface [] customDeserializersList) {
GsonBuilder gsonBuilder = new GsonBuilder();
if(customDeserializersList != null) {
for(GeneralCustomDeserializerInterface customDeserializer : customDeserializersList)
gsonBuilder.registerTypeAdapter(customDeserializer.getDeserializedClass(), customDeserializer);
}
return gsonBuilder.create();
}
@Provides
public Retrofit provideRetrofitInstance(@Named("base_url") String baseURL, Gson gson) {
return new Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create(gson))
//.callFactory(okHttpClient)
.build();
}
@Provides
public InterfaceRequests provideInterfaceRequests(Retrofit retrofit) {
return retrofit.create(InterfaceRequests.class);
}
I think you misunderstood subcomponent. Object in a subcomponent can't be used by the component. The relation is only in the opposite direction (subcomponent can use object from the main component)
I think in your case you should use a network module in AppComponent