背景
根据同级子组件之间的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模块中的所有绑定都将暴露于该子组件。虽然,我只想提供“ 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?感谢您提供任何解释,更改我的配置的建议或指向可能解决我的问题的文章的链接。注意,只有暴露为供应方法的绑定才可以通过组件依赖项获得。
您应该为此目的使用组件依赖项。
下面是工作示例
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}")
}
我使用了作用域,因为我想每个应用程序只需要一个存储库实例。如果不清楚,请通知我。