随着Kodein依赖注入,我不想传遍各处的kodein实例

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

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更多信息,请阅读ConfigurableKodein的Kodein 3.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实例作为替代。