2016-04-10 12 views
0

我有一個基於play framework構建的web應用程序。配置圖中的scala類名

我的一個端點提供了由不同類的輸出組成的響應。消費者可以選擇他希望在響應中輸出哪些片段: GET /model/:modelId?fields=length,width,age。 因此,我有LengthProvider,WidthProvider。 現在,我想在控制器的配置圖,像

val providers = Map(
    "length" -> LengthProvider, 
    "width" -> WidthProvider 
) 

能夠通過此圖,以過濾用戶的輸入和應用所有的供應商,如

fields.collect { 
    case field if providers.contains(field) => providers(field)(db).get(modelId) 
    } 

問題出現時,我嘗試構建相應的類。 我有一個抽象FieldProvider

abstract class FieldProvider(db: DB) { 
    def get(modelId: Long): Future[Seq[Writes]] 
} 

和相應的實施方式中(LengthProviderWidthProvider)。現在,爲了配置Map編譯,我需要爲我想引用的類定義伴隨對象(例如,我需要LengthProvider對象)。然後,當我使用Map(類名)的值時,我不能像正常那樣初始化類實例,我只能訪問伴隨對象中定義的apply方法。但問題是這不是我定義的抽象類的一部分,因此編譯器不理解方法簽名(因爲它只在子類的伴隨對象中定義,而不在父抽象類中定義):

fields.collect { 
    case field if providers.contains(field) => providers(field)(db).get(modelId) 
                   ↑ won't compile 
    } 

有沒有辦法讓伴侶對象的apply簽名部分的抽象類?還是有另一種更好的方法?

回答

1

由於地圖中的實例woud實際上是compaion對象,你不需經過讓伴侶從對象功能1例如爲:

object LengthProvider extends ((DB) => LengthProvider) { 
    def apply(v1: DB): LengthProvider = new LengthProvider(v1) 
} 

object WidthProvider extends ((DB) => WidthProvider) { 
def apply(v1: DB): WidthProvider = new WidthProvider(v1) 
} 

val providers: Map[String, ((DB) => FieldProvider)] = Map(
    "length" -> LengthProvider, 
    "width" -> WidthProvider 
) 
+0

繼承這個工作好!現在我有一個問題,實際上'LengthProvider'也需要一個隱含的參數。可以以某種方式將它通過伴隨對象中的這個'apply'方法轉發嗎? –