Grails: добавление динамических методов в плагин - PullRequest
0 голосов
/ 28 января 2010

Я разрабатываю плагин, который добавляет метод getFlashHelper к каждому контроллеру. Этот метод должен возвращать экземпляр класса FlashHelper.

Однако конструктору класса FlashHelper необходимо передать экземпляр контроллера, на котором был вызван метод getFlashHelper.

Надеюсь, следующий код объяснит, что я делаю немного лучше

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[])
    }
}

Код, кажется, работает, но я не могу избавиться от ощущения, что должен быть более простой способ сделать это. Эта последняя строка особенно ужасна. Можно ли как-нибудь это упростить?

Спасибо, Дон

1 Ответ

1 голос
/ 28 января 2010

Поскольку контроллеры создаются для каждого запроса, я бы сохранил помощника как атрибут запроса:

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
   }
}
...