2016-07-25 48 views
2

使用Kodein,我发现我必须传递kodein实例或将它们注入模块和类。但是有时候我有些课程如此分离,我希望他们能够发现“一个真正的Kodein”。由于这是一个服务器端应用程序,并且我只有一个Kodein范围,所以它应该很容易。我可以创建一个全局对象,如:随着Kodein依赖注入,我不想传遍各地的kodein实例

val kodeinGlobal: Kodein = Kodein { ... } 

但是,当一些模块都在不同的项目中重复使用,不工作,我们不能轻易共享这一个实例。也许一个单独的模块只是为了保持全球的工作,但那么它将需要是一个var,我宁愿它不可改变。

Kodein能自己找到一个主要的,顶级的或全球性的范围吗?

注:这个问题是故意写的,并回答了作者(Self-Answered Questions),这样就常见的成语答案科特林/ Kodein主题存在于SO。

回答

4

在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阅读Kodein 3.x docs for ConfigurableKodein,以及有关预定义的全局实例The God Complex: One True Kodein

作为帮手,您可以使用新的KodeinGlobalAware界面在您的课堂中自然地访问Kodein instanc而无需直接参考全球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,无论这是全局实例还是特定的实例,请参阅:Injecting Kodein instances within binding declarations作为替代方案。