使用Kodein,我发现我必须传递Kodein实例或将其注入(inject)模块和类中。但是有时候我的类(class)是如此的脱节,以至于我希望他们能够发现“一个真正的科登”。由于这是一个服务器端应用程序,而且我只有一个Kodein范围,因此应该很容易。我可以创建一个全局对象,例如:
val kodeinGlobal: Kodein = Kodein { ... }
但是,当某些模块在不同项目中重复使用时,这是行不通的,并且我们无法轻松共享此实例。也许只需要一个单独的模块来保存全局变量就可以了,但是那时它需要是一个
var
,我希望它不可更改。Kodein能否自行找到主要,顶级或全局范围?
注意:这个问题是作者故意写并回答的(Self-Answered Questions),因此SO中常见的Kotlin / Kodein主题的惯用答案是存在的。
最佳答案
在Kodein 3.x
中,有一个名为kodein-conf
的新模块。这样,您可以创建Kodein的可修改实例(只要您在第一次注入(inject)之前对其进行了修改),并且如果需要,它还包含一个Kodein全局实例供共享使用。这与普通的Kodein实例相反,后者必须在构造时定义所有绑定(bind),并且永远不能修改。
使用预定义的全局变量与引用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
的更多信息,请阅读Kodein 3.x
docs for ConfigurableKodein和预定义的全局实例The God Complex: One True Kodein。作为帮助者,您可以使用新的
KodeinGlobalAware
接口(interface)在类中自然访问Kodein实例,而不必直接引用全局Kodein实例。例如,通过添加此接口(interface),您可以仅调用实例创建方法,例如:class DefaultSomeService(): SomeService, KodeinGlobalAware {
val mapper: ObjectMapper = instance()
// ...
}
或者,如果您有一个案例(例如测试),除非要被特定实例覆盖,否则您要使用全局实例,则可以执行以下操作:
class DefaultSomeService(override val kodein: Kodein = Kodein.global): SomeService, KodeinAware {
val mapper: ObjectMapper = instance()
// ...
}
它使用
KodeinAware
接口(interface)并覆盖其抽象成员变量kodein
以在类内进行相同的透明注入(inject)类型,同时默认使用global
实例。如果只想注入(inject)Kodein,无论是全局实例还是特定实例,请参见:Injecting Kodein instances within binding declarations作为替代。
关于dependency-injection - 使用Kodein依赖注入(inject),我不想到处传递Kodein实例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38573125/