开发者

Grails: adding dynamic methods within a plugin

I'm developing a plugin that adds a getFlashHelper method to each controller. This method should return an instance of a FlashHelper class.

Howev开发者_如何学运维er, the constructor of the FlashHelper class must be passed the instance of the controller on which the getFlashHelper method was called.

Hopefully the following code will explain what I'm doing a bit better

def doWithDynamicMethods = {ctx ->

    application.controllerClasses*.metaClass*.getFlashHelper = {

        def controllerInstance = delegate

        // Avoid creating a new FlashHelper each time the 'flashHelper' property is accessed
        if (!controllerInstance.metaClass.hasProperty('flashHelperInstance')) {
            controllerInstance.metaClass.flashHelperInstance = new FlashHelper(controller: controllerInstance)
        }

        // Return the FlashHelper instance. There may be a simpler way, but I tried
        // controllerInstance.metaClass.getMetaProperty('flashHelperInstance')
        // and it didn't work
        return controllerInstance.metaClass.getMetaProperty('flashHelperInstance').getter.invoke(controllerInstance, [] as Object[])
    }
}

The code appears to work, but I can't help feeling that there must be an easier way of doing this. That last line is particularly gruesome. Is there any way I can simplify this?

Thanks, Don


Since controllers are created per-request, I'd store the helper as a Request attribute:

for (c in grailsApplication.controllerClasses) {
   c.clazz.metaClass.getFlashHelper = { ->
      def controllerInstance = delegate
      def request = controllerInstance.request
      def helper = request['__flash_helper__']
      if (!helper) {
         helper = new FlashHelper(controller: controllerInstance)
         request['__flash_helper__'] = helper
      }
      helper
   }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜