Previously I had only one AppComponent with four modules (AppModule, NetworkModule, StorageModule, PresentersModule) and injected singletons everywhere. Recently, I decided to make small refactoring in my app and divide it into scopes. I think, presenters can live within activities only, so I created @ActivityScope and ActivityModule, but the project cannot be compiled because of my misunderstanding how to mix these scopes. I've read a lot of articles and questions at stackoverflow, but everywhere there are simple examples where modules are independent. In my case such thing as
@Singleton
@Component(modules = { AppModule.class, StorageModule.class, NetworkModule.class })
public interface AppComponent {
ActivityComponent plus(PresentersModule module); // <-- error
}
is not working. I get this error:
Error:(19, 1) error: com.my.package.di.component.ActivityComponent scoped with @com.my.package.di.scope.ActivityScope may not reference bindings with different scopes:
@Provides @Singleton android.app.Application com.my.package.di.module.AppModule.provideApplication()
@Provides @Singleton com.my.package.network.FeedBurnerApi com.my.package.di.module.NetworkModule.provideFeedBurnerApi(android.app.Application)
@Provides @Singleton android.database.sqlite.SQLiteOpenHelper com.my.package.di.module.StorageModule.provideSQLiteOpenHelper(android.app.Application)
@Provides @Singleton com.my.package.storage.Repository com.my.package.di.module.StorageModule.provideRepository(android.database.sqlite.SQLiteOpenHelper)
@Provides @Singleton com.my.package.SharedPreferencesHelper com.my.package.di.module.StorageModule.provideSharedPreferencesHelper(android.app.Application)
So, the question is how I can get the instance of my ActivityComponent?
You can see dependencies between modules below:
Application module:
@Module
public final class AppModule {
private final MyApplication mApplication;
public AppModule(MyApplication application) { ... }
@Provides @Singleton Application provideApplication() { ... }
}
Network module:
@Module(includes = { AppModule.class })
public final class NetworkModule {
@Provides @Singleton FeedBurnerApi provideFeedBurnerApi(Application application) { ... }
@Provides @Singleton Retrofit provideRetrofit() { ... }
}
Storage module:
@Module(includes = { AppModule.class })
public final class StorageModule {
@Provides @Singleton Repository provideRepository(SQLiteOpenHelper sqLiteOpenHelper) { ... }
@Provides @Singleton SQLiteOpenHelper provideSQLiteOpenHelper(Application application) { ... }
@Provides @Singleton SharedPreferencesHelper provideSharedPreferencesHelper(Application application) { ... }
}
Presenters module:
@Module(includes = { AppModule.class, NetworkModule.class, StorageModule.class })
public final class PresentersModule {
@Provides FeedPageViewPresenter provideFeedPageViewPresenter(FeedBurnerApi api, Repository repository, SharedPreferencesHelper preferences) { ... }
@Provides @ActivityScope SlidingTabsViewPresenter provideSlidingTabsViewPresenter(Repository repository) { ... }
}
Application component:
@Singleton
@Component(modules = { AppModule.class, StorageModule.class, NetworkModule.class })
public interface AppComponent {}
Activity component:
@Subcomponent(modules = PresentersModule.class)
@ActivityScope
public interface ActivityComponent {
void inject(FeedPageView view);
void inject(SlidingTabsView view);
}
The problem was in my PresentersModule.
Since Subcomponents have access to entire objects graph from their parents, I don't need to include these dependencies in my sub-module. So, I changed this code:
@Module(includes = { AppModule.class, NetworkModule.class, StorageModule.class })
public final class PresentersModule { ... }
with this:
@Module
public final class PresentersModule { ... }
and it solved my issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With