【问题标题】:How to use dependencies from another Module with Dagger2 in Android?如何在 Android 中通过 Dagger2 使用来自另一个模块的依赖项?
【发布时间】:2022-01-07 14:29:45
【问题描述】:

所以我有 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)
}
}

Home 组件:

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

interface HomeComponent {
    fun inject(homeFragment: HomeFragment)
}

【问题讨论】:

    标签: android kotlin dagger-2


    【解决方案1】:

    它不起作用,因为它们彼此无关。 解决办法是:

    HomeComponent

    @FragmentScope
    @Subcomponent(
        modules = [HomeModule::class]
    )
    
    interface HomeComponent {
        fun inject(homeFragment: HomeFragment)
    }
    
    @Scope
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    annotation class FragmentScope
    

    说明:我们应该使用 HomeComponent 作为 AppCompnentsubcomponent 并且我们应该使用另一个 annotation 以避免冲突.

    AppComponent

    @Singleton
    @Component(modules = [AppModule::class])
    interface AppComponent {
    
        fun getHomeFragmentCompnent():HomeComponent
    
        @Component.Builder
        interface Builder {
            fun build(): AppComponent
    
            @BindsInstance
            fun application(application: Application): Builder
        }
    }
    

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

    @FragmentScope
    class AnyFragment:Fragment {
    
        @Inject
        lateinit var dao: HomeDao 
    
        //in onCreateView
        val component = ((application as YourApplcation).applicationComponent)
            .getHomeFragmentCompnent().inject(this)
    }
    

    【讨论】:

    • 这行得通,不是在片段中调用(requireActivity().application as App).appComponent.homeComponent().inject(this) 的另一种方法吗?只是想知道
    猜你喜欢
    • 2015-04-05
    • 2018-03-13
    • 1970-01-01
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 2012-04-01
    • 2021-09-12
    相关资源
    最近更新 更多