Dependency injection 使用Kodein依赖项注入,我不需要';我不想到处传播kodein实例

Dependency injection 使用Kodein依赖项注入,我不需要';我不想到处传播kodein实例,dependency-injection,kotlin,kodein,Dependency Injection,Kotlin,Kodein,使用Kodein,我发现我必须传递Kodein实例或将它们注入模块和类中。但有时我的类是如此的不连贯,我希望它们能够发现“一个真正的Kodein”。因为这是一个服务器端应用程序,我只有一个Kodein示波器,所以应该很容易。我可以创建全局对象,例如: class DefaultSomeService(): SomeService, KodeinGlobalAware { val mapper: ObjectMapper = instance() // ... } val-kod

使用Kodein,我发现我必须传递Kodein实例或将它们注入模块和类中。但有时我的类是如此的不连贯,我希望它们能够发现“一个真正的Kodein”。因为这是一个服务器端应用程序,我只有一个Kodein示波器,所以应该很容易。我可以创建全局对象,例如:

class DefaultSomeService(): SomeService, KodeinGlobalAware {
    val mapper: ObjectMapper = instance()
    // ...
}
val-kodeinGlobal:Kodein=Kodein{…}
但是,当一些模块在不同的项目中重复使用时,这就行不通了,我们无法轻松地共享这个实例。也许一个单独的模块可以用来保存全局变量,但它需要是一个
var
,我更希望它不可更改

Kodein能自己找到主范围、顶级范围或全局范围吗


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

在Kodein
3.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
的更多信息,请阅读,并了解预定义的全局实例

作为助手,您可以使用新的
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
在类中执行相同的透明注入类型,同时默认为
全局
实例

如果您只想注入Kodein,无论它是全局实例还是特定实例,请参阅:作为备选方案