从父android模块访问Dagger子组件依赖项

Eix*_*ixx 11 android module dagger dagger-2

最近我开始将我们的应用程序划分为更小的Android模块,但是我很难让Dagger以我想要的方式工作.

我目前的匕首设置包括:
- ApplicationComponent标有@Singleton.此组件是在app start上创建的.
- UserSubComponent标有@UserScope.用户登录时创建此子组件.

这两个组件都app与我的App班级一起放在我的模块中,班级负责创建两个组件.

在我的login模块(这是我的应用程序模块的父级,因此它无法访问应用程序模块中的任何内容)我有我的AuthenticationManager.当我使用RxJava用户登录到从我的信号AuthenticationManagerApp,所以UserSubComponent可以被创建.

我的问题是我需要UserSubComponent在创建之后访问我的一些依赖项,AuthenticationManager因此我可以在继续之前预先加载用户的数据.

模块结构:

              app (AppComponent & UserSubComponent)
                                ^
                                |
  login (AuthenticationManager) - feature 2 - feature 3
Run Code Online (Sandbox Code Playgroud)

我的App类:

class App : DaggerApplication() {

    @Inject
    lateinit var authenticationManager: AuthenticationManager

    override fun onCreate() {
        super.onCreate()

        authenticationManager
            .authenticationStateStream
            .subscribe { state ->
                if (state == AuthenticationState.AUTHENTICATED) {
                    AppInjector.userComponent.inject(this)
                }
    }
}
Run Code Online (Sandbox Code Playgroud)

AuthenticationManager会:

class AuthenticationManager @Inject constructor(loginApi: LoginApi) {

    @Inject
    lateinit var preLoader : PreLoader // This won't work because of different scope

    val authenticationStateStream = Observable<AuthenticationState>()

    fun login() {
        if (success) {
            authenticationStateStream.emit(AuthenticationState.AUTHENTICATED)
            // UserSubComponent is now created
            preLoader.preload()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

应用组件

@Singleton
@Component(modules = [AppModule::class, AndroidSupportInjectionModule::class])
interface AppComponent : AndroidInjector<App> {

    fun userComponentBuilder(): UserComponent.Builder
}
Run Code Online (Sandbox Code Playgroud)

的AppModule

@Module
class AppModule {
    @Provides
    @Singleton
    fun provideLoginApi() = LoginApi()
}
Run Code Online (Sandbox Code Playgroud)

UserSubComponent

@UserScope
@Subcomponent(modules = [UserModule::class, AndroidSupportInjectionModule::class])
interface UserComponent : AndroidInjector<App> {

    @Subcomponent.Builder
    interface Builder {
        fun build(): UserComponent
    }

}
Run Code Online (Sandbox Code Playgroud)

UserModule

@Module
class UserModule {
    @Provides
    @UserScope
    fun providesPreLoader() = PreLoader()
}
Run Code Online (Sandbox Code Playgroud)

我可以以某种方式使这个结构工作?或者说模块+匕首有什么选择?

Eix*_*ixx 2

因此,经过多次尝试,我终于解决了我的问题。

我发现的是:

  • 当您的应用程序分为多个模块时,请勿使用子组件。
  • 每个模块都需要它自己的组件(功能组件)

我发现这篇文章非常有帮助: https://proandroiddev.com/using-dagger-in-a-multi-module-project-1e6af8f06ffc