2016-07-25 93 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作爲替代方案。