gropapa
gropapa

Reputation: 577

Dagger 2 Activity context/ApplicationContext modules

I'm struggling with dagger 2 in order to understand how i can pass a context or another according to my needs. - First I have an ApplicationModule annotated @Singleton since it provides hi level objects like the webservice object, the model ..., generally those objects are passed the ApplicationContext (since the y need to live during the whole Application lifetime)

@Singleton
@dagger.Component(modules = {
    AppModule.class
})
public interface AppComponent {
        void inject(MyApp application);
        Model model();
        Context context();<--- should provide the application Context for the Object above (model)
...

the implementation looks like that

@dagger.Module
public class AppModule {

    private final Application app;
    public ApplModule(Application app) {
        this.app = app;
    }

    @Provides
    @Singleton
    Model provideModel(Bus bus) {
        return new Model(bus);
    }

    @Provides
    @Singleton
    Context provideApplicationContext() {
        return app.getApplicationContext();
    }
...

Well the point is I am certainly missing something...but I can't figure what, maybe I misundestood the use of Scopes

Upvotes: 8

Views: 3831

Answers (2)

j2emanue
j2emanue

Reputation: 62519

you can use qualifiers like this. in two separate files define the following:

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityContext {
}

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface ApplicationContext {
}

then in your ActivityModule do this:

@Provides
@ActivityScope
@ActivityContext
public Context context() {
    return activity;
}

and likewise in your appmodule do this:

 @Provides
    @Singleton
@ApplicationContext
    Context provideApplicationContext() {
        return app.getApplicationContext();
    }

now we have a way to ask for whatever type of context we need based on the qualifier @ApplicationContext and @ActivityContext.

so for example in your activity you could do this:

  @Inject @ApplicationContext
    Context c;

which would inject an application context.

and in a module you could do this for example:

  @Provides
    @ActivityScope
    LoginPresenter provideLoginPresenter(@ActivityContext Context context) {
        return new LoginPresenter(context);
    }

to provide an activity context. this is just an example.

Upvotes: 5

IgorGanapolsky
IgorGanapolsky

Reputation: 26821

@Named is a requirement if you want to provide multiple objects of the same type from your module.

As far as your second question, in regards to passing the correct Activity context, you need to have this in your ActivityComponent:

Activity activity();

Upvotes: 0

Related Questions