2014-07-25 79 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似乎也不起作用。下图对我有用