sat
sat

Reputation: 41106

Injecting Singleton class using Dagger 2.x

I have two components, one for Application Context and one for Activity Context as shown below.

@Singleton
@Component(modules = {AppModule.class,})

public interface AppComponent {
    @ForApplication
    Context context();

    //Preferences prefs(); //(Question is related to this line)
}

@PerActivity
@Component(dependencies = AppComponent.class,modules = {ActivityModule.class})
public interface ActivityComponent extends AppComponent {
  void inject(ActivityA activity);
}

I have a Singleton class that I want to inject in ActivityA that is declared in ActivityComponent.

@Singleton
public class Preferences {
@Inject
    public Preferences(@ForApplication Context context) {
        ...
    }
}

public class ActivityA extends AppCompatActivity {
        @Inject
        Preferences preferences;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

           DaggerActivityComponent.builder()
                        .appComponent(((MyApplication) getApplication()).getComponent())
                        .activityModule(new ActivityModule(this))
                        .build();

}

I am injecting AppComponent in my Applicaiton onCreate() and ActivityComponent in onCreate of Activity, in this case ActivityA like above

Problem(or Question): Currently, If I do not expose this singleton class from my AppComponent (The commented line in first code block) and do not have provides method in AppModule. I cannot compile. Compilation Error shows I cannot have a reference to different scope from ActivityComponent, which I kind of understand. That means, I cannot access Singleton scoped class with PerActivity scoped component.

But, do I have to have provides method for all Singleton class and expose it via AppComponent (which I am currently doing and works)? Is there a better way to do the Singleton class injection?

Upvotes: 3

Views: 1758

Answers (1)

R. Zagórski
R. Zagórski

Reputation: 20268

There is another way. Declare Activity component as Application subcomponent. This way everything declared in Application component is visible in Activity subcomponent. Access to the Activity subcomponent can be done through Acpplication component:

GithubClientApplication.get(this)
            .getAppComponent()
            .provide(new ActivityModule(this))

Have a look at this excellent article about Dagger components, especially in Implementation section.

Upvotes: 2

Related Questions