2013-06-24 77 views
2

我想解決一個Config對象一個類型安全的配置對象,說config1與其他說config2解決與其他

唯一的公共API,允許類的東西是config1.withFallback(config2).resolve()。然而,這增加了從config2config1的條目,這不是我們想要的。

在一些調查中,我們發現了一個名爲ResolveContext所提供的方法應該是一個非公共類。所以我們正在利用反射。我們當前的代碼:

object ConfigImplicits { 
    implicit class RichConfig(val config: Config) extends AnyVal { 
    def resolveWith(source: Config): Config = { 
     val resolver = resolveContext.getDeclaredMethod(
     "resolve", 
     abstractConfigValue, 
     abstractConfigObject, 
     configResolveOptions 
    ) 
     resolver.setAccessible(true) 
     resolver.invoke(
     null, 
     config.underlyingAbstractConfigObject, 
     source.underlyingAbstractConfigObject, 
     ConfigResolveOptions.defaults 
    ).asInstanceOf[ConfigObject].toConfig 
    } 

    def underlyingAbstractConfigObject = { 
     val f = simpleConfig.getDeclaredField("object") 
     f.setAccessible(true) 
     f.get(config) 
    } 
    } 

    val resolveContext = Class forName "com.typesafe.config.impl.ResolveContext" 
    val abstractConfigValue = Class forName "com.typesafe.config.impl.AbstractConfigValue" 
    val abstractConfigObject = Class forName "com.typesafe.config.impl.AbstractConfigObject" 
    val configResolveOptions = classOf[ConfigResolveOptions] 
    val simpleConfig = Class forName "com.typesafe.config.impl.SimpleConfig" 
} 

我們認識到,依靠非公開內臟可能不是一個好主意。所以:

  1. 有沒有公開的方法,我們不知何故錯過了,它已經這樣做了?
  2. 如果不是,我們是否應該提出拉動要求?

回答

1

沒有AFAIK的公共方法。一個較脆弱的解決方法不是依賴私有API,而是先解析源對象作爲回退,然後迭代源解析對象中的密鑰,然後從目標對象中刪除那些不需要的密鑰。

我想不出有任何理由不添加Config.resolveWith(),但我不知道是否有一個理由,因爲我記得考慮它。也許我只是覺得沒人會用它。

如果你拉的請求,一定要包括測試和文檔。我認爲pull請求是合理的,假設它代碼非常少(正如我所期望的)。當前主分支開放API添加,以顯示在最終的1.2版本中。

+0

看起來有些主持人濫用自己的權利,並刪除了我這裏發表最後一次評論。爲了正確地繼續溝通,我會重複我發佈的內容(根據我所記得的內容):「謝謝,我會分叉並嘗試添加方法,如果我成功了,請提出請求。」如承諾的那樣,我嘗試過,但層次結構似乎奇怪地糾纏在一起,我無法添加該方法。 [1/2] – missingfaktor

+0

您提出的解決方法對我們來說不起作用,因爲原始配置已經有了這些密鑰。我們不希望它們被替換,這就是爲什麼而不是使用'withFallback'來編寫我們的'resolveWith'(它使用反射)。 – missingfaktor

+2

對於未來的旁觀者,現在有一個resolveWith()API可用。 –