2014-07-25 106 views
0

我正在尋找創建一種方法來根據scala中的模板ID動態調用邏輯。因此,模板ID 1調用邏輯a,模板ID 2調用邏輯b等。邏輯將是多樣的,但將具有相同的輸入/輸出。另外,不同的模板ID的數量將會進入數千個,並且不會提前知道,所以鬆耦合感覺要走。在scala中使用反射的動態對象方法調用

我已經開始尋找反射來做到這一點使用Scala 2.11.1,並可以靜態地使用反射,當我知道提前使用的邏輯,但還沒有找到正確的方式來動態使用反射,例如傳入模板id 2將調用邏輯b。

下面是一個簡化的例子,展示了靜態版本的工作原理以及迄今爲止的動態版本的框架。

package thePackage 

import scala.reflect.runtime.{universe => ru} 

trait theTrait { def theMethod(x: String): Unit } 

// the different logic held in different objects 
object object1 extends theTrait { 
    def theMethod(x: String) = { println("a " + x) } 
} 

object object2 extends theTrait { 
    def theMethod(x: String) = { println("b " + x) } 
} 

object object3 extends theTrait { 
    def theMethod(x: String) = { println("c " + x) } 
} 

// run static/dynamic reflection methods 
object ReflectionTest { 

    // "static" invocation calling object1.theMethod 
    def staticInvocation() = { 
    val m = ru.runtimeMirror(getClass.getClassLoader) 
    val im = m.reflect(thePackage.object1) 
    val method = ru.typeOf[thePackage.object1.type] 
        .decl(ru.TermName("theMethod")).asMethod 
    val methodRun = im.reflectMethod(method) 
    methodRun("test") 
    } 

    staticInvocation 

    // "dynamic" invocation using integer to call different methods 
    def dynamicInvocation(y: Integer) = { 
    val m = ru.runtimeMirror(getClass.getClassLoader) 
    val module = m.staticModule("thePackage.object" + y) 
    val im = m.reflectModule(module) 

    // stuck... static approach does not work here 

    } 

    dynamicInvocation(1) 
    dynamicInvocation(2) 
    dynamicInvocation(3) 

} 

什麼需要添加/改變dynamicInvocation方法,使這項工作,或者我應該使用不同的方法?

回答

4

您需要獲取您的模塊的實例鏡像,您可以在其中反映該方法。

def dynamicInvocation(y: Integer) = { 
    val m = ru.runtimeMirror(getClass.getClassLoader) 
    val module = m.staticModule("thePackage.object" + y) 
    val im = m.reflectModule(module) 
    val method = im.symbol.info.decl(ru.TermName("theMethod")).asMethod 

    val objMirror = m.reflect(im.instance) 
    objMirror.reflectMethod(method)("test") 
} 
+0

作品魅力,感謝您的快速回復 –

1

看來上面的解決方案中的TermName方法已被newTermName替換,而且info.decl似乎也不起作用。下圖對我有用