С инъекцией кодеиновой зависимости я не хочу везде передавать экземпляры кодеина

Используя 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 в декларации привязки в качестве альтернативы.

Другие вопросы по тегам