有一种无需实际构造函数调用即可提供实例的方法。

class ModelImpl @Inject constructor(...): Model{}

@Provides
fun model(inst: ModelImpl): Model = inst

如果没有接口(interface),有没有办法做同样的事情? 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提供无界面的实例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53769442/

    10-12 17:41