Предоставить экземпляр без интерфейса, используя Dagger - PullRequest
0 голосов
/ 13 декабря 2018

Есть способ предоставить экземпляр без фактического вызова конструктора.

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

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

Есть ли способ сделать то же самое, если нет интерфейса?Dagger уже знает все зависимости для ModelImpl, поэтому он может создать экземпляр.

Это, очевидно, дает цикл зависимости:

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

Ответы [ 2 ]

0 голосов
/ 14 декабря 2018

дополнение к David Medenjak ответ.Если нет интерфейса и нет необходимости группировать экземпляры в модули, то модуль может быть полностью опущен:

class Model @Inject constructor(...){
  //...
}

@Component
interface SomeComponent{
  fun model(): Model
}

val model = someComponent.model()
0 голосов
/ 14 декабря 2018

Когда вы используете инжектор конструктора, Dagger может создать объект для вас, и вы уже используете Dagger для создания ModelImpl, чтобы использовать его в качестве привязки для Model в вашем примере!

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 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

Рекомендую начать с небольшого примера, затем скомпилировать проект и взглянуть на сгенерированный код.Если что-то не так, вы сразу же получите ошибки, а можете поиграться и попробовать разные настройки!

...