我有一个组件:具有@CarScope 作用域的CarComponent 和具有作用域@DriverScope 的子组件DriverSubcomponent。基本上汽车需要司机,司机需要头盔。
这是汽车组件:
@DriverScope
@Subcomponent(modules=[HelmetModule::class])
interface DriverComponent {
fun getDriver(): Driver
@Subcomponent.Builder
interface Builder {
fun build(): DriverComponent
}
}
还有一个驱动子组件:
@Module
interface HelmetModule {
@Binds
fun bindHelmet(whiteHelmet: WhiteHelmet): Helmet
}
头盔模块:
@CarScope
class Car @Inject constructor(@Named("CNAME") private val name: String, private val driver: Driver) {
override fun toString(): String {
return "Car: $name, Driver: $driver, hash: ${super.toString()}"
}
}
以及相应的类:
class Driver @Inject constructor (@Named("DNAME") private val driverName: String, private val helmet: Helmet){
override fun toString(): String{
println("Driver Name: $driverName")
println("Helmet info: $helmet")
println (super.toString())
return super.toString()
}
}
interface Helmet {
fun putOn(): Boolean
fun takeOff(): Boolean
}
class WhiteHelmet @Inject constructor() : Helmet {
override fun putOn(): Boolean {
println("White Helmet is on")
return true
}
override fun takeOff(): Boolean {
println("White Helmet is off")
return false
}
override fun toString(): String {
return "White Helmet"
}
}
(modules = [HelmetModule::class])
我注意到除非我将 public function getZoneFromCustomer()
{
$zone = array();
$this->db->query("SELECT zone_id FROM " . DB_PREFIX . "address WHERE address_id = '". (int)$this->customer->getAddressId() ."'");
foreach ($query->rows as $result) {
$zone = $result['zone_id'];
}
return $zone;
}
添加到 CarComponent,否则此代码将无法编译。好像我调用getCar()的时候,并没有使用DriverComponent提供的Driver,而是创建了所有需要的对象,
我的目标是使用 DriverComponent 提供的 Driver。
实现这一目标的方法有哪些? 当前行为是否与我使用的自定义范围有关?
谢谢。 莱塞克
答案 0 :(得分:0)
DriverComponent 是 CarComponent 的子组件。 CarComponent 是一个顶级组件。这意味着:
无论您的范围如何,以上所有内容都是正确的;你可以删除它们,它仍然是真的。但是,由于您使用的是范围:
如果以上听起来对您来说是正确的——DriverComponent 只能从 CarComponent 实例中创建,在 CarComponent 创建之后——那么您的用例与 Dagger Subcomponents for encapsulation 文档相匹配。您需要做的就是绑定 DriverComponent 的单个 @CarScope
实例,您可以使用可注入的 DriverComponent.Builder 创建该实例。然后,您可以放心地将 HelmetModule
和 driverName
分别移至 DriverComponent 及其构建器。
@Provides @CarScope DriverComponent provideDriverComponent(DriverComponent.Builder builder) {
return builder.build()
}
或者在 Kotlin 中:
@Provides @CarScope
fun provideDriverComponent(builder: DriverComponent.Builder) = builder.build()
您的 Car 将无法直接访问您的 Driver 或他们的 Helmet,但您可以通过向 DriverComponent 添加方法并从该实例中获取它们来访问它们。您甚至可以通过注入 DriverComponent 并返回 driverComponent.helmet
来编写一个在 CarComponent 中返回 Helmet 的提供程序。
如果这看起来不对——也许你的 DriverComponent 不需要任何 CarComponent 绑定,并且你的 Driver 应该能够在没有 CarComponent 实例的情况下创建——那么你可能需要避免使用 Subcomponent 并让你的 Driver或 DriverComponent 传递到您的 CarComponent.Builder。