如何在 Android 中将来自另一个模块的依赖项与 Dagger2 一起使用?

How to use dependencies from another Module with Dagger2 in Android?

所以我有 AppModule 和 HomeModule。 我想在 HomeModule 中使用应用程序上下文和 AppModule 中的 AppDatabase。

我收到此错误: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
}
}

这是 AppModule:

@Module
class AppModule {

@Provides
@Singleton
fun provideAppDatabase(app: Application): AppDatabase{
    return Room.databaseBuilder(
        context,
        AppDatabase::class.java,
        "app_db"
    )
        .build()
}

}

@Module

如何在 HomeModule 中使用 AppModule 依赖项(在本例中为 AppDatabase 和应用程序)?

@Module
class HomeModule {

@Provides
@Singleton
fun provideHomeDao(appDatabase: AppDatabase): HomeDao {
    return appDatabase.homeDao
}

@Provides
@Singleton
fun provideHomeRepository(homeDao: HomeDao): HomeRepository {
    return HomeRepositoryImpl(homeDao)
}
}

主页组件:

@Singleton
@Component(
    modules = [HomeModule::class]
)

interface HomeComponent {
    fun inject(homeFragment: HomeFragment)
}

它不会起作用,因为它们彼此无关。 解决方案是:

HomeComponent:

@FragmentScope
@Subcomponent(
    modules = [HomeModule::class]
)

interface HomeComponent {
    fun inject(homeFragment: HomeFragment)
}

@Scope
@Documented
@Retention(RetentionPolicy.RUNTIME)
annotation class FragmentScope

说明:我们应该使用 HomeComponent 作为 subcomponent for AppCompnent 我们应该使用另一个注释以避免冲突。

AppComponent:

@Singleton
@Component(modules = [AppModule::class])
interface AppComponent {

    fun getHomeFragmentCompnent():HomeComponent

    @Component.Builder
    interface Builder {
        fun build(): AppComponent

        @BindsInstance
        fun application(application: Application): Builder
    }
}

然后在你的片段中你可以像这样使用它,例如:

@FragmentScope
class AnyFragment:Fragment {

    @Inject
    lateinit var dao: HomeDao 

    //in onCreateView
    val component = ((application as YourApplcation).applicationComponent)
        .getHomeFragmentCompnent().inject(this)
}