С инъекцией кодеиновой зависимости я не хочу везде передавать экземпляры кодеина
Используя Kodein, я обнаружил, что должен передавать экземпляры kodein или вводить их в модули и классы. Но иногда у меня есть классы, которые так отключены, что я хочу, чтобы они просто могли обнаружить "одного настоящего Кодейна". Поскольку это приложение на стороне сервера, и у меня есть только одна область действия Кодеина, это должно быть легко. Я могу создать глобальный объект, такой как:
val kodeinGlobal: Kodein = Kodein { ... }
Но это не работает, когда некоторые модули повторно используются в разных проектах, и мы не можем легко поделиться этим одним экземпляром. Может быть, отдельный модуль просто для хранения глобальных будет работать, но тогда это должно быть var
и я бы предпочел, чтобы это не было изменчивым.
Может ли Kodein самостоятельно найти основной, высокоуровневый или глобальный охват?
Примечание: этот вопрос намеренно написан и получен ответ от автора ( Вопросы с самоотвечением), так что идиоматические ответы на часто задаваемые темы Kotlin/Kodein присутствуют в SO.
1 ответ
В кодейне 3.x
доступен новый модуль под названием kodein-conf
, Это позволяет вам создавать модифицируемый экземпляр Kodein (при условии, что вы изменяете его до выполнения первой инъекции), и он также содержит глобальный экземпляр Kodein для совместного использования, если это необходимо. Это противоречит нормальному экземпляру Кодейна, который должен иметь все привязки, определенные во время построения, и никогда не может быть изменен.
Использовать предопределенный глобал так же просто, как ссылаться Kodein.global
, И он работает так же, как любой настраиваемый экземпляр Kodein:
Kodein.global.addImport(someModule) // add other modules to it
val something: SomethingCool = Kodein.global.instance() // inject from it
Если вы хотите сделать свой собственный глобальный:
val kodeinGlobal = ConfigurableKodein()
Подробнее о ConfigurableKodein
читать кодейн 3.x
документы для ConfigurableKodein и о предопределенном глобальном экземпляре The God Complex: One True Kodein
В качестве помощника вы можете использовать новый KodeinGlobalAware
интерфейс для естественного доступа в вашем классе к экземплярам Kodein без прямой ссылки на глобальный экземпляр Kodein. Например, добавив этот интерфейс, вы можете просто вызвать методы создания экземпляра, такие как:
class DefaultSomeService(): SomeService, KodeinGlobalAware {
val mapper: ObjectMapper = instance()
// ...
}
Или, если у вас есть случай (например, тестирование), где вы хотите использовать глобальный экземпляр, если он не переопределен конкретным экземпляром, вы можете сделать что-то похожее на:
class DefaultSomeService(override val kodein: Kodein = Kodein.global): SomeService, KodeinAware {
val mapper: ObjectMapper = instance()
// ...
}
Который использует KodeinAware
интерфейс и и переопределяет его абстрактную переменную-член kodein
сделать такой же прозрачный тип инъекций в классе, по умолчанию global
пример.
Если вы хотите внедрить только кодеин Kodein, будь то глобальный или конкретный экземпляр, см. Инъекцию экземпляров Kodein в декларации привязки в качестве альтернативы.