0

我希望能够将类型信息公开给通用抽象类中的子组件。我们有一个abstract class在子类中设置的类型参数(后者绑定在我们的图中),并尝试将此类型信息传递给此类内的子组件。尝试的方式尝试将类型参数附加到子组件。

这是我想要实现的更充实的示例:

interface Runner<T> {
    fun run(t: T)
}

data class Data<T>(
    val options: T
)

abstract class AbstractRunner<Options> : Runner<Data<Options>> {

    @Inject
    lateinit var mySubcomponentBuilder: MySubcomponent.Builder<Options>

    // Constructing this relies on dynamicData which must be generated at runtime
    // (hence the subcomponent)
    // @Inject
    // lateinit var subRunner: Runner<Options>

    override fun run(data: Data<Options>) {

        // Some dynamically generated data - we can't use assisted injection as this is injected into other classes in
        // the subgraph.
        val dynamicData = Random.nextInt()

        mySubcomponentBuilder
            .dynamicData(dynamicData)
            .build()
            .subcomponentRunner()
            .run(data.options)
    }
}

// We have other objects with associated Runner implementations;
// we list one for brevity.
object Foo
class MyRunner @Inject constructor() : AbstractRunner<Foo>()
class SubRunner @Inject constructor(s: String) : Runner<Foo> {
    override fun run(t: Foo) {}
}

@Component(modules=[MyModule::class])
interface MyComponent {
    fun runner(): Runner<Data<Foo>>
}

@Module(subcomponents=[MySubcomponent::class])
interface MyModule {
    @Binds
    fun bindMyRunner(runner: MyRunner): Runner<Data<Foo>>
}

// This does not work due to generics being banned on (Sub)Components.
@Subcomponent(modules=[SubModule::class])
interface MySubcomponent<T> {
    // We can't parameterise the method; generics are banned on methods in (Sub)Components.
    fun subcomponentRunner(): Runner<T>

    @Subcomponent.Builder
    interface Builder<U> {
        @BindsInstance
        fun dynamicData(i: Int): Builder<U>
        fun build(): MySubcomponent<U>
    }
}

@Module
object SubModule {
    @Provides
    fun provideString(i: Int) = i.toString()
    @Provides
    fun provideSubRunner(s: String): Runner<Foo> = SubRunner(s)
}

当然,这并不需要:

error: @Subcomponent.Builder types must not have any generic types

是否可以通过其他方式连接这些信息?如果不需要在我们的子组件中绑定的变量,我们可以将我们的变量绑定到我们subRunner: Runner<Options>的主图中而不会出现问题,正如评论的那样。

4

0 回答 0