Dagger 2: Unable to enter singleton in another area

I have a Singleton scoped module that provides some standard singletones: application, database services, etc. But for Activity, I have a separate module that Presenter should create for its Activity, and I need to pass the application context to it. However, when I try to compile the project, I get the following error:

Error:(13, 1) error: xxx.SplashComponent scoped with @xxx.ViewScope may not reference bindings with different scopes: @Provides @Singleton xxx.ApplicationModule.provideAppContext() 

Here is a snippet of my application module:

 @Singleton @Module public class ApplicationModule { private Application app; public ApplicationModule(Application app) { this.app = app; } @Provides @Singleton @Named("ui") Scheduler provideUIScheduler() { return AndroidSchedulers.mainThread(); } @Provides @Singleton @Named("io") Scheduler provideIOScheduler() { return Schedulers.io(); } @Provides @Singleton Application provideApplication() { return app; } @Provides @Singleton Context provideAppContext() { return app; } } 

And here is the activity module and component:

 @Module public class SplashModule { private final FragmentManager fragmentManager; public SplashModule(FragmentManager fragmentManager) { this.fragmentManager = fragmentManager; } @Provides @ViewScope Presenter getPresenter(Context context) { return new SplashPresenter(context, fragmentManager); } } 

component:

 @ViewScope @Component(modules = {SplashModule.class, ApplicationModule.class}) public interface SplashComponent { void inject(SplashActivity activity); } 

What am I doing wrong?

+6
source share
2 answers

What am I doing wrong?

It:

 @ViewScope @Component(modules = {SplashModule.class /*View scoped*/, ApplicationModule.class/*Singleton scoped*/}) 

You can only include unmodulated modules or modules with a scope with the same scope in your components. You will need to use more than one component.

To include dependencies from your application, you must have them in another component, for example. ApplicationComponent . If you do this, you have 2 options: declare SplashComponent as SubComponent of ApplicationComponent or add ApplicationComponent as a dependency on your component. If you add it as a dependency, be sure to specify the methods in the ApplicationComponent so that it can access the dependencies.

eg. if you should use component dependencies:

 @Component(modules = {ApplicationModule.class}) public interface ApplicationComponent { void inject(MyApplication app); // todo: also add getters for your other dependencies you need further down the graph Application getApplication(); } @Component(modules = {SplashModule.class}, dependencies={ApplicationComponent.class}) public interface SplashComponent { // as before } 
+8
source

I want to explain some key points related to Dagger 2 from my understanding.

The main participants:

A β€œcomponent” is a bridge between the modules and the places where the injection takes place.

A β€œmodule” is the place where we declare our objects to be introduced.

The scale is similar to the lifetime of a related injection history.

How does it work?

-Declare component with scope ("Singleton").

-Define the objects that can insert the provided objects into the component module.

void inject (BaseFragment baseFragment);

******* Provide the provided objects in the component module to subcomponents ****
DbHelper dbHelper ();

-Declare and provides objects that need to be inserted through the component.

Example:

 @Singleton @Component(modules = { ApplicationModule.class, NetworkModule.class }) public interface ApplicationComponent { void inject(BaseActivity baseActivity); DbHelper dbHelper(); } @PerService @Component(dependencies = ApplicationComponent.class, modules = ServiceModule.class) public interface ServiceComponent { void inject(SyncService service); } 

//SyncService.java

  @Inject DbHelper dbHelper; (even Singleton scoped) private void setupInjector() { ServiceComponent mServiceComponent = DaggerServiceComponent.builder() .applicationComponent(getApplicationComponent()) .serviceModule(new ServiceModule(this)) .build(); mServiceComponent.inject(this); } 

ok then ... enter image description here

You can embed objects with a scope without cloud and (Singleton and PerService) in your SyncService.class

+4
source

All Articles