Dagger: How can we add a module to Subcomponent.Builder in version 2.10-rc2?

Created on 5 Mar 2017  路  7Comments  路  Source: google/dagger

With the new functionality, we can inject Activity and Fragment using a single AndroidInjection.inject(this) call. But how can we pass a module to Subcomponent's builder?

For example, Activity's subcomponent has a module which needs this Activity in the constructor.

```java
@ActivityScope
@Subcomponent(modules = SplashActivitySubcomponent.SplashActivityModule.class)
public interface SplashActivitySubcomponent extends AndroidInjector {
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder {
}

@Module
abstract class SplashActivityModule extends ActivityModule<SplashActivity> {
    SplashActivityModule(SplashActivity activity) {
        super(activity);
    }

    @ActivityScope
    @Provides
    SplashContract.View provideView() {
        return activity;
    }

    @ActivityScope
    @Provides
    SplashContract.Presenter providePresenter(SplashPresenter presenter) {
        return presenter;
    }
}

}

Most helpful comment

Sorry to tag on this issue, I am currently doing something else to achieve the same effect.

Is it a bad idea?

@ActivityScope @Subcomponent(modules = { MyActivityModule.class })
public interface MyActivityComponent extends AndroidInjector<MyActivity> {
  @Subcomponent.Builder abstract class Builder extends AndroidInjector.Builder<MyActivity> {
    public abstract Builder myActivityModule(MyActivityModule myActivityModule);

    @Override public void seedInstance(MyActivity instance) {
      myActivityModule(new MyActivityModule(instance));
    }

    public abstract MyActivityComponent build();
  }
}

If I should post on SO or create anew issue just tell me.

All 7 comments

Dupe of #610

Sorry to tag on this issue, I am currently doing something else to achieve the same effect.

Is it a bad idea?

@ActivityScope @Subcomponent(modules = { MyActivityModule.class })
public interface MyActivityComponent extends AndroidInjector<MyActivity> {
  @Subcomponent.Builder abstract class Builder extends AndroidInjector.Builder<MyActivity> {
    public abstract Builder myActivityModule(MyActivityModule myActivityModule);

    @Override public void seedInstance(MyActivity instance) {
      myActivityModule(new MyActivityModule(instance));
    }

    public abstract MyActivityComponent build();
  }
}

If I should post on SO or create anew issue just tell me.

@JonathanMerritt, thank you. Nice solution.

@AntonyGolovin I'd suggest you look at the linked issue that @JakeWharton mentioned.

@JonathanMerritt - that does work, but it's unnecessary. the seedInstance method provides the activity instance into the graph, so you can have MyActivityModule with no state, and just request MyActivity in your @Provides methods.

class MyActivityModule {
  @Provides
  static SomethingDerivedFromMyActivity providesMethod(MyActivity myActivity) {
    return myActivity.somethingDerived();
  }
}

Doing this saves the module instance and allows the generated factories to be leaner.

@ronshapiro Thank you. It did seem a little clunky. I think for some reason putting the Activity through as a method parameter felt wrong.

It's nice to know the instance can just be accessed like that though, very cool.

@ronshapiro That's a really useful technique to know - it would be great if it could be mentioned in the docs. Would you be interested in a PR for that?

@vaughandroid sure, I'd be happy to review it

Was this page helpful?
0 / 5 - 0 ratings