有一种方法可以在不调用实际构造函数的情况下提供实例。
class ModelImpl @Inject constructor(...): Model{}
@Provides
fun model(inst: ModelImpl): Model = inst
如果没有界面,有没有办法做到同样的事情? Dagger
已经知道 ModelImpl
的所有依赖项,因此它可以创建一个实例。
这显然给出了依赖循环:
@Provides
fun model(inst: ModelImpl): ModelImpl = inst
最佳答案
当您使用构造函数注入(inject)时,Dagger 可以为您构造对象,并且您已经在使用 Dagger 创建 ModelImpl
并将其用作示例中 Model
的绑定(bind)!
class ModelImpl @Inject constructor(...): Model{}
@Provides
fun model(inst: ModelImpl): Model = inst
// somewhere else...
// both variants would work!
@Inject lateinit var modelImpl : ModelImpl
@Inject lateinit var model : Model
没有界面同样可以工作
class ModelImpl @Inject constructor(...)
// somewhere else...
@Inject lateinit var model : ModelImpl
如果您注释构造函数,则 Dagger 可以为您创建对象(如果可以解析所有依赖项)。无论您在哪里请求对象/依赖项,这都是一样的,
- 作为
@Provides
带注释的方法中的参数(如您的示例) - 作为字段注入(inject)属性 (
@Inject Lateinit var
) - 作为另一个对象构造函数中的参数
- 作为组件中的提供方法 (
fun getFoo() : Foo
)
以下所有内容都可以
// foo and bar can both be constructor injected
class Foo @Inject constructor()
class BarImpl @Inject constructor(val foo : Foo) : Bar
@Module
interface BarModule() {
@Binds // you should prefer Binds over Provides if you don't need initialization
// barImpl can be constructor injected, so it can be requested/bound to its interface here
fun bindBar(bar : BarImpl) : Bar
}
@Component(modules = BarModule::class)
interface BarComponent {
fun getBar() : Bar // returns barImpl due to binding
}
@Inject lateinit var bar : BarImpl // but we could as well use the implementation directly
@Inject lateinit var bar : Foo // or just foo
我建议您从一个小示例开始,然后编译项目并查看生成的代码。如果出现问题,您会立即收到错误消息,同时您可以尝试不同的设置!
关于kotlin - 使用 Dagger 提供没有接口(interface)的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53769442/