2

使用 Kodein,我发现我必须传递 kodein 实例或将它们注入到模块和类中。但有时我的课程如此脱节,我希望他们能够发现“一个真正的 Kodein”。由于这是一个服务器端应用程序,而且我只有一个 Kodein 范围,所以应该很容易。我可以创建一个全局对象,例如:

val kodeinGlobal: Kodein = Kodein { ... }

但是当一些模块在不同的项目中重复使用时,这不起作用,我们不能轻易地共享这个实例。也许一个单独的模块只是为了保存全局会起作用,但是它需要是 avar并且我希望它是不可更改的。

Kodein 可以自己找到一个主要的、顶级的或全局的范围吗?

注意: 这个问题是作者有意编写和回答的(自我回答的问题),因此常见的 Kotlin/Kodein 主题的惯用答案出现在 SO 中。

4

1 回答 1

5

在 Kodein3.x中有一个可用的新模块,称为kodein-conf. 这允许您创建一个可修改的 Kodein 实例(只要您在第一次注入完成之前对其进行修改),如果需要,它还包含一个用于共享使用的 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阅读 ConfigurableKodein 的Kodein3.x文档的更多信息,以及有关预定义全局实例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 实例作为替代方案。

于 2016-07-25T16:33:54.077 回答