kotlin 你能配置Dagger2默认创建Component.Factory而不是Component.Builder吗?

4nkexdtk  于 9个月前  发布在  Kotlin
关注(0)|答案(1)|浏览(77)

我有一个依赖图,它由许多匕首组件组成;分为4层,组件也依赖于父组件。
当我定义一个组件时;我配置它们的依赖项,有时只有1个依赖项,有时甚至多达6个父组件。通常这些父组件是新组件的唯一依赖项,所以dagger为我创建了一个Component.Builder,我可以用它来示例化组件。
然而,就我所知,对于一个Component.Builder,你不会得到编译时检查来验证你在Builder中提供的所有需求。有了Component.Factory,你就可以进行编译时检查。
所以我的问题是,有没有可能使默认方法也是编译时安全的?例如,通过强制dagger生成一个工厂类而不是默认的构建器类?
当我得到一个运行时异常而不是编译时错误时的例子:

// Define 3 layers of components
@AppScope
@Component()
interface AppComponent {
    fun provisionSomething(): Something
}

@EnvironmentScope
@Component(
    dependencies = [AppComponent::class]
)
interface EnvironmentComponent {
    fun provisionEnvironment(): Environment
}

@ActivityScope
@Component(
    dependencies = [AppComponent::class, EnvironmentComponent::class]
)
interface FeatureComponent {
    fun inject(viewModel: MyViewModel)
}

// create components
fun getAppComponent(): AppComponent = TODO("not relevant for example")
fun getEnvironmentComponent(): EnvironmentComponent = TODO("not relevant for example")
fun getFeatureComponent(): FeatureComponent {
    return DaggerFeatureComponent
        .builder()
        .appComponent(getAppComponent())
        //.environmentComponent(getEnvironmentComponent()) // This will compile just fine, but crash only runtime
        .build()
}

如图所示,当您忘记更新组件的示例化时,请确保调用了所有相关的构建器方法,编译时安全性将不复存在。
如果我自己重新配置我的MixureComponent来创建一个Factory,我又有了编译时安全性。然而,在一个团队中工作,我希望有一种方法可以更好地强制这种编译时安全性;例如,具有改变默认行为的编译器标志,或者可能是其它的东西。
谢谢.

ef1yzkbh

ef1yzkbh1#

不,这是目前不支持的,如果它 * 是 * 存在,它会有缺点。
首先是:理想情况下,我们不应该首先依赖于自动生成的构建器,更不用说工厂了。就像在google/dagger#935中一样,生成API的源代码生成器被认为比生成实现的生成器更难使用,这是影响Dagger设计的因素之一,你写一个接口(组件,子组件,构建器,工厂等),Dagger生成它的实现。其中一个原因是,对于生成的接口,您的IDE或构建系统将需要运行源代码生成器来确定API表面本身;如果系统仅生成实现,则仍然可以在不调用整个源代码生成器的情况下确定接口。Dagger默认情况下确实提供了一个Builder,但是提供自己的Builder(命名控制,@BindsInstance,文档,IDE支持)的好处是强烈建议您编写自己的Builder。
还有:

  • 模块没有自然的顺序。它可以是简单的类名字母顺序,CCN字母顺序,或其他完全。为了知道添加新模块或依赖项的顺序,您必须检查生成的代码。(我最初也建议模块遍历顺序,深度优先或广度优先,但想象一下,如果模块顺序或传递包含发生变化,参数顺序会发生变化,这将是多么不和谐。
  • 模块可以是可选的,特别是对于具有默认构造函数的可示例化模块。Factory的当前实现要求您选择并且不支持多个工厂方法,尽管设计文档将其作为扩展打开。因此,对于工厂来说,比构建器更不真实的是,Dagger为您编写了一个足够可预测的实现。
  • Builder和Factory目前不能共存,如果它们共存,则必须跟踪它们是否需要提供哪些@BindsInstance绑定。这些当前在Builder或Factory上定义。
  • 如果你要为Builders和Factory做一个配置选项,因为它们目前不能共存,你需要详细地为每个类定义它,或者为每个构建定义它,并希望没有人依赖于同一构建中生成的Builders和生成的Factory。(你可以同时做这两件事,但这会使它变得更加复杂,特别是对于可重用的模块/组件/库。

总之,自动生成的工厂会有一些主要的可用性问题。他们目前还没有得到支持(虽然我不是匕首团队的成员,也没有以任何官方身份发言),如果他们很快得到支持,我会感到惊讶。
顺便说一句,我没有在google/dagger issues list中找到自动生成Factory的功能请求,但是Factory功能本身被提议为google/dagger#1317,并且有一个posted design doc,讨论了Factory vs Builder的适用性和不适用性。

相关问题