17

I am not quite sure how to solve this with dagger 2. Lets assume we have ApplicationModule that provides us ApplicationContext then we have ApplicationComponent that uses just this one module. Then on top of it we have ActivityModule and ActivityComponent that has dependency on ApplicationComponent. ActivityComponent is build just like

    ApplicationComponent component = ((MyApplication) getApplication()).getComponent();

    mComponent = Dagger_ActivityComponent.builder()
            .applicationComponent(component)
            .activityModule(new ActivityModule(this))
            .build();

And then I inject my activity:

mComponent.inject(this);

Now I am able to use everything that is declared inside my ActivityModule, however it is not possible for me to access ApplicationModule.

So the question is how could that be achieved? So that when I build component that depends on another component I can still access module from the first one?

EDIT

I think I have found solutions, after rewatching Devoxx talk by Jake again, I have had to miss that out, whatever I want to use from another components module I have to provide in that component, for example I want to use Context from ApplicationModule then inside ApplicationComponent I have to state Context provideContext(); and it is going to be available. Pretty cool :)

Community
  • 1
  • 1
user3274539
  • 687
  • 2
  • 8
  • 18

1 Answers1

17

You have already answered your question, but the answer is to specify the provision methods in your "superscoped" component (ApplicationComponent).

For example,

@Module
public class ApplicationModule {
    @Provides
    @Singleton
    public Something something() {
        return new Something.Builder().configure().build(); 
           // if Something can be made with constructor, 
           // use @Singleton on the class and @Inject on the constructor
           // and then the module is not needed
    }
}

@Singleton
@Component(modules={ApplicationModule.class})
public interface ApplicationComponent {
    Something something(); //PROVISION METHOD. YOU NEED THIS.
}

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {
}

@ActivityScope
public class OtherThing {
    private final Something something;

    @Inject
    public OtherThing(Something something) {
        this.something = something;
    }
}

@Component(dependencies = {ApplicationComponent.class})
@ActivityScope
public interface ActivityComponent extends ApplicationComponent { //inherit provision methods
    OtherThing otherThing();
}
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428