15.8 Adding Dynamic Methods at Runtime 2.3.8

See the light - agile, industrial strength, rapid web application development made easy

(Quick Reference) # 15.8 Adding Dynamic Methods at Runtime - Reference Documentation Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari Version: 2.3.8 ## 15.8 Adding Dynamic Methods at Runtime #### The Basics Grails plugins let you register dynamic methods with any Grails-managed or other class at runtime. This work is done in a `doWithDynamicMethods` closure. For Grails-managed classes like controllers, tag libraries and so forth you can add methods, constructors etc. using the ExpandoMetaClass mechanism by accessing each controller's MetaClass:
    class ExamplePlugin {
        def doWithDynamicMethods = { applicationContext ->
            for (controllerClass in application.controllerClasses) {
                 controllerClass.metaClass.myNewMethod = {-> println "hello world" }
            }
        }
    }
In this case we use the implicit application object to get a reference to all of the controller classes' MetaClass instances and add a new method called `myNewMethod` to each controller. If you know beforehand the class you wish the add a method to you can simply reference its `metaClass` property. For example we can add a new method `swapCase` to `java.lang.String`:

    class ExamplePlugin {    def doWithDynamicMethods = { applicationContext ->
            String.metaClass.swapCase = {->
                 def sb = new StringBuilder()
                 delegate.each {
                     sb << (Character.isUpperCase(it as char) ?
                            Character.toLowerCase(it as char) :
                            Character.toUpperCase(it as char))
                 }
                 sb.toString()
            }        assert "UpAndDown" == "uPaNDdOWN".swapCase()
        }
    }
#### Interacting with the ApplicationContext The `doWithDynamicMethods` closure gets passed the Spring `ApplicationContext` instance. This is useful as it lets you interact with objects within it. For example if you were implementing a method to interact with Hibernate you could use the `SessionFactory` instance in combination with a `HibernateTemplate`:

    import org.springframework.orm.hibernate3.HibernateTemplateclass ExampleHibernatePlugin {   def doWithDynamicMethods = { applicationContext ->       for (domainClass in application.domainClasses) {           domainClass.metaClass.static.load = { Long id->
                    def sf = applicationContext.sessionFactory
                    def template = new HibernateTemplate(sf)
                    template.load(delegate, id)
               }
           }
       }
    }
Also because of the autowiring and dependency injection capability of the Spring container you can implement more powerful dynamic constructors that use the application context to wire dependencies into your object at runtime:

    class MyConstructorPlugin {    def doWithDynamicMethods = { applicationContext ->
             for (domainClass in application.domainClasses) {
                  domainClass.metaClass.constructor = {->
                      return applicationContext.getBean(domainClass.name)
                  }
             }
        }
    }
Here we actually replace the default constructor with one that looks up prototyped Spring beans instead! | Quick Reference (hide)