Reputation: 345
So i Have AppModule and HomeModule. I would like to use in HomeModule the Application context and AppDatabase from AppModule.
I'm getting this error: AppDatabase cannot be provided without an @Provides-annotated method. public abstract interface HomeComponent
@Singleton
@Component(
modules = [AppModule::class]
)
interface AppComponent {
@Component.Builder
interface Builder {
fun build(): AppComponent
@BindsInstance
fun application(application: Application): Builder
}
}
This is the AppModule:
@Module
class AppModule {
@Provides
@Singleton
fun provideAppDatabase(app: Application): AppDatabase{
return Room.databaseBuilder(
context,
AppDatabase::class.java,
"app_db"
)
.build()
}
}
@Module
How can i use the AppModule dependencies(in this case AppDatabase and the Application) in the HomeModule ?
@Module
class HomeModule {
@Provides
@Singleton
fun provideHomeDao(appDatabase: AppDatabase): HomeDao {
return appDatabase.homeDao
}
@Provides
@Singleton
fun provideHomeRepository(homeDao: HomeDao): HomeRepository {
return HomeRepositoryImpl(homeDao)
}
}
The HomeComponent:
@Singleton
@Component(
modules = [HomeModule::class]
)
interface HomeComponent {
fun inject(homeFragment: HomeFragment)
}
Upvotes: 1
Views: 1265
Reputation: 438
It will not work because they are unrelated to each other. The solution is:
The HomeComponent:
@FragmentScope
@Subcomponent(
modules = [HomeModule::class]
)
interface HomeComponent {
fun inject(homeFragment: HomeFragment)
}
@Scope
@Documented
@Retention(RetentionPolicy.RUNTIME)
annotation class FragmentScope
Explanation: We should use HomeComponent as subcomponent for AppCompnent and we should use another annotation to avoid conflict.
The AppComponent:
@Singleton
@Component(modules = [AppModule::class])
interface AppComponent {
fun getHomeFragmentCompnent():HomeComponent
@Component.Builder
interface Builder {
fun build(): AppComponent
@BindsInstance
fun application(application: Application): Builder
}
}
Then in your Fragment you can use it like this, for example:
@FragmentScope
class AnyFragment:Fragment {
@Inject
lateinit var dao: HomeDao
//in onCreateView
val component = ((application as YourApplcation).applicationComponent)
.getHomeFragmentCompnent().inject(this)
}
Upvotes: 2