Dagger 2-如何通过子组件或组件依赖关系建立同级依赖

  

背景

根据兄弟姐妹子组件之间的docs依赖关系是不可能的,因此,剩下的另一种方法是组件依赖关系。我试图封装“资源库”类,以便UI只能访问“资源库”的实例,而不能访问“资源库”的实现细节。我的意思是 ApiModule 中的任何内容都不应公开。

ApiModule

@Module
class ApiModule {
    @Provides
    fun provideConnection(): Connection = //....   
}

RepositoryModule

@Module (
    includes = [
        ApiModule::class
    ]
)
abstract class RepositoryModule {
    @Provides
    fun providesRepository(connection Connection): Repository = //.....
}

AppComponent

@Component (modules = [
    AppModule::class,RepositoryModule::class
])
interface AppComponent{
    @Component.Builder
    interface Builder {

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

问题

现在,如果我创建一个 AppComponent 的子组件(比如说 activitySubComponent ),则所有绑定都在 RepositoryModule ApiModule 模块将公开给该子组件。不过,我只想提供“存储库”,即可从 activitySubComponent

访问
  

建议的解决方案

创建 RepositoryComponenet activityComponent 组件使 AppComponenet 成为其依赖项:

AppComponent

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

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

activityComponent

@Component(dependencies = [AppComponent::class],modules = [activityModule::class])
interface activityComponent {
    fun inject(mainactivity: Mainactivity)

    @Component.Builder
    interface Builder{

        fun appComponent(appComponent: AppComponent): Builder

        fun build(): activityComponent
    }
} 

RepositoryComponent

@Component(dependencies = [AppComponent::class],modules = [RepositoryModule::class])
interface RepositoryComponent {
}

问题是如何将“资源库”实例公开给同级 activityComponent 的绑定,或者将@Inject公开给Mainactivity?任何解释,更改我的配置的建议或可能解决我问题的文章的链接都将受到赞赏。

xiaomao315452522 回答:Dagger 2-如何通过子组件或组件依赖关系建立同级依赖

如果我正确理解了您的问题,则您不想将AppComponent的所有依赖项公开给它的子组件。正如component documentation所说的(“组件依赖关系”部分)

  

请注意,只有通过供应方式公开的绑定才可以通过组件依赖项获得。

您应该为此目的使用组件依赖项。

下面是工作示例

class Connection
interface Repository

@Module
object AppModule {
    @Provides
    @Singleton
    fun provideConnection() = Connection()
}

@Module(includes = [AppModule::class])
object RepositoryModule {
    @Provides
    @Singleton
    fun provideRepository(connection: Connection) = object : Repository {}
}

@Singleton
@Component(modules = [AppModule::class,RepositoryModule::class])
interface AppComponent {
    val repository: Repository
}

@Scope
@MustBeDocumented
@kotlin.annotation.Retention
annotation class ActivityScope

@ActivityScope
@Component(dependencies = [AppComponent::class])
interface ActivityComponent {
    fun inject(activity: FakeActivity)
}

class FakeActivity {
    @Inject
    lateinit var repository: Repository
    //    uncomment this and code won't compile because connection isn't explicitly exposed in AppComponent
    //    @Inject
    //    lateinit var connection: Connection
}

fun main() {
    val appComponent = DaggerAppComponent.create()
    val activityComponent = DaggerActivityComponent.builder().appComponent(appComponent).build()
    val fakeActivity = FakeActivity()
    activityComponent.inject(fakeActivity)
    println("hash: ${fakeActivity.repository}")
    println("hash: ${appComponent.repository}")
}

我使用了作用域,因为我想每个应用程序只需要一个存储库实例。如果不清楚,请告诉我。

本文链接:https://www.f2er.com/3150535.html

大家都在问