Ответ 1
Я не могу проверить это прямо сейчас, но я думаю, что это должно работать:
@Module
object AModule {
@JvmStatic
@Provides
fun providesA(): A = A()
}
В последних версиях кинжала 2 одним из улучшений является возможность использования статических методов обеспечения. Просто так:
@Provides
static A providesA() {
return A();
}
Мне было интересно, как это сделать в котлине? Я пробовал
@Module
class AModule {
companion object {
@JvmStatic
@Provides
fun providesA(): A = A()
}
}
Но я получаю сообщение об ошибке:
@Provides methods can only be present within a @Module or @ProducerModule
Я предполагаю, что здесь что-то происходит с объектом-компаньоном, однако я совершенно новичок в Kotlin, и я не уверен, как это можно сделать. Возможно ли это?
Спасибо!
Я не могу проверить это прямо сейчас, но я думаю, что это должно работать:
@Module
object AModule {
@JvmStatic
@Provides
fun providesA(): A = A()
}
Хотя я думаю, что решение zsmb13 лучше, я нашел другое решение, которое работает
@Module
class AModule {
@Module
companion object {
@JvmStatic
@Provides
fun providesA(): A = A()
}
// add other non-static provides here
}
Однако обратите внимание, что будут два сгенерированных класса: AModule_ProvidesAFactory
и AModule_Companion_ProvidesAFactory
, а не один AModule_ProvidesAFactory
класс для случая с объектом вместо класса с сопутствующим объектом
Отличное объяснение, которое, похоже, одобрено Google, находится на https://github.com/google/dagger/issues/900
В частности, см.:
Статическое обеспечение может быть достигнуто через @JvmStatic. Я вижу, что есть два сценария:
top-level
object
s
@Module object DataModule {
@JvmStatic @Provides fun
provideDiskCache() = DiskCache()
}
Если у вас есть существующий класс модуль, вещи становятся немного страннее
@Module abstract class DataModule {
@Binds abstract fun provideCache(diskCache: DiskCache): Cache
@Module
companion object {
@JvmStatic @Provides fun provideDiskCache() = DiskCache()
}
}
Это работает следующим образом:
сопутствующий объект также должен быть аннотирован как @Module под капотом, компилятор kotlin будет дублировать эти статические методы в класс DataModule. Кинжал увидит их и будет относиться к ним как регулярные статические поля. Кинжал тоже увидит их в спутнике объект, но этот "модуль" получит код gen из кинжала, но будет помечен как "неиспользованный". В среде IDE это будет помечено как таковое, как provideDiskCache. метод будет помечен как неиспользованный. Вы можете сказать IntelliJ игнорировать это для аннотаций, аннотированных @Provides с помощью quickfix
Для статического подхода мне нравится решение zsmb13.
Однако я пришел сюда, потому что хотел объединить @Provides
и @Binds
в одном модуле.
Это невозможно сделать напрямую, но с двумя вложенными модулями (как указывал Омар Аль Халаби).
Я выбрал немного другой подход для объединения @Provides
и @Binds
:
@Module(includes = [MyModule.Bindings::class])
object MyModule {
@Module
interface Bindings {
@Binds
fun bindA(a: AImpl): A
}
@Provides
@JvmStatic
fun provideB(): B = BImpl()
}
Различия:
companion object
.abstract
как в классе, так и в функции.