Reputation: 577
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();
}
...
secondly I have an Activity Scope componenet in with I provide the current activity and different views which need a Context.
@ActivityScope
@Component(
dependencies = AppComponent.class
, modules = {ActivityModule.class}
)
public interface ActivityComponent {
void inject(MyActivity activity);
Context context(); <---should provide the activity's context
MyView homeView(); <----takes a Context as a contructor parameter
@Module public class ActivityModule { private final Activity activity;
public ActivityModule(Activity activity) {
this.activity = activity;
}
@Provides
@ActivityScope
public Activity activity() {
return activity;
}
@Provides
@ActivityScope
@Named("viewcontext") <----- if I removed this I get an error from Dagger
public Context context() {
return activity;
}
@Provides
@ActivityScope
MyView provideZeView(Bus bus, Model model) { <---- previously receiving the ApplicationContext as a parameter
MyView v = new MyView(activity, bus, model); <---- must pass the activity otherwise passing the Context reveived is the ApplicationContext
return v;
}
so Here are my questions:
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
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
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