我有一个依赖图,它由许多匕首组件组成;分为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,我又有了编译时安全性。然而,在一个团队中工作,我希望有一种方法可以更好地强制这种编译时安全性;例如,具有改变默认行为的编译器标志,或者可能是其它的东西。
谢谢.
1条答案
按热度按时间ef1yzkbh1#
不,这是目前不支持的,如果它 * 是 * 存在,它会有缺点。
首先是:理想情况下,我们不应该首先依赖于自动生成的构建器,更不用说工厂了。就像在google/dagger#935中一样,生成API的源代码生成器被认为比生成实现的生成器更难使用,这是影响Dagger设计的因素之一,你写一个接口(组件,子组件,构建器,工厂等),Dagger生成它的实现。其中一个原因是,对于生成的接口,您的IDE或构建系统将需要运行源代码生成器来确定API表面本身;如果系统仅生成实现,则仍然可以在不调用整个源代码生成器的情况下确定接口。Dagger默认情况下确实提供了一个Builder,但是提供自己的Builder(命名控制,@BindsInstance,文档,IDE支持)的好处是强烈建议您编写自己的Builder。
还有:
@BindsInstance
绑定。这些当前在Builder或Factory上定义。总之,自动生成的工厂会有一些主要的可用性问题。他们目前还没有得到支持(虽然我不是匕首团队的成员,也没有以任何官方身份发言),如果他们很快得到支持,我会感到惊讶。
顺便说一句,我没有在google/dagger issues list中找到自动生成Factory的功能请求,但是Factory功能本身被提议为google/dagger#1317,并且有一个posted design doc,讨论了Factory vs Builder的适用性和不适用性。