Java – dagger 2 component dependency
Is it possible to inject something into the module?
I have 2 basic modules / components:
@Component(modules = {OkHttpModule.class}) public interface OkHttpComponent extends AppComponent { OkHttpClient provideOkHttpClient(); } @Module public class OkHttpModule { @Provides OkHttpClient provideOkHttpClient() { return mHttpClient; } }
@Component(modules = {GsonModule.class}) public interface GsonComponent extends AppComponent { Gson provideGson(); } @Module public class GsonModule { @Provides Gson provideGson() { return mGson; } }
With this module / component, I want to create a third module:
@Component(dependencies = {OkHttpComponent.class,GsonComponent.class},modules = {RetrofitModule.class}) public interface RetrofitComponent extends AppComponent { API provideAPI(); } @Module public class RetrofitModule { @Inject OkHttpClient mHttpClient; @Inject Gson mGson; @Provides VeentsMeAPI provideVeentsMeAPI() { return mVeentsMeAPI; } }
However, mhttpclient and mgson were not injected Is it possible to inject something into the module? If so, how?
I created this component:
okHttpComponent = DaggerOkHttpComponent.builder() .okHttpModule(new OkHttpModule(this)) .build(); gsonComponent = DaggerGsonComponent.builder() .gsonModule(new GsonModule()) .build(); retrofitComponent = DaggerRetrofitComponent.builder() .retrofitModule(new RetrofitModule()) .okHttpComponent(okHttpComponent) .gsonComponent(gsonComponent) .build();
Solution
In my opinion, the injection module is not important According to the dagger1 definition of the module, all modules are declared as complete = false and Library = true, which means that as long as you include modules that are not in the component you use, you do not need to specify any real magic or link your component dependencies to each other, so that each dependency you can inject can be specified in only one component
You will get the dependencies of other modules in the constructor parameters You need to include modules in the include list, or you need to specify modules in the component in the same scope
The correct way is to do this:
@Module public class OkHttpModule { @Provides @ApplicationScope public OkHttpClient okHttpClient() { return new OkHttpClient(); } } @Module public class GsonModule { @Provides @ApplicationScope public Gson gson() { return new Gson(); } } @Module(includes={GsonModule.class,OkHttpModule.class}) //look closely,this is the magic public class RetrofitModule { @Provides @ApplicationScope public VeentsMeAPI veentsMeAPI(Gson gson,OkHttpClient okHttpClient) { //dependencies! return RestAdapter.Builder() .setClient(new Client(okHttpClient)) .setConverter(new GsonConverter(gson)) .create(VeentsMeAPI.class); } }
And then
@Scope @Retention(RetentionPolicy.RUNTIME) public @interface ApplicationScope {}
then
@ApplicationScope @Component(modules={RetrofitModule.class}) //contains all other modules/dependencies public interface AppComponent { OkHttpClient okHttpClient(); Gson gson(); VeentsMeAPI veentsMeAPI(); void inject(Something something); }
and
Then you'll get what's generated, and you have to build it together
AppComponent appComponent = DaggerAppComponent.create(); //use appComponent.inject(stuff); with `void inject(Stuff stuff);` methods defined in AppComponent
Component dependencies are the same as subcomponents, so these dependencies are the same as subcomponents, so they are not applicable to inheriting dependencies from the same scope The same range of dependencies should be in the same component, just different modules