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

问题描述 投票:0回答:1

背景

根据同级子组件之间的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),则RepositoryModuleApiModule模块中的所有绑定都将暴露于该子组件。虽然,我只想提供“ Repository”,才能从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?感谢您提供任何解释,更改我的配置的建议或指向可能解决我的问题的文章的链接。
dagger-2 dagger
1个回答
0
投票
如果我正确理解了您的问题,您不想将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}") }

我使用了作用域,因为我想每个应用程序只需要一个存储库实例。如果不清楚,请通知我。
© www.soinside.com 2019 - 2024. All rights reserved.