0

I have an abstract class that many classes extend. Everything is in src/groovy.

In my abstract class I would like to have a service injected that the child classes would inherit so I don't have to inject them in every single one.

abstract class Animal {

    def noiseService

    abstract Sound getSound()

}

class Dog extends Animal {

    Sound getSound() {
        noiseService.bark()
    }

}

In my resources.groovy:

animal(com.thepound.Animal) { bean ->
    noiseService = ref("noiseService")
}

This produced an error saying it couldn't instantiate the class because it is abstract, so I added this to the definition:

    bean.abstract = true

Now I no longer get an error, however the services are always null in my child classes. How can I get this to work?

James Kleeh
  • 12,094
  • 5
  • 34
  • 61

2 Answers2

1

Here is what I ended up doing.

I followed Burt Beckwith's post here http://burtbeckwith.com/blog/?p=1017 to create an ApplicationContextHolder class.

Then

abstract class Animal {

    def noiseService = ApplicationContextHolder.getBean("noiseService")

    abstract Sound getSound()

}

Now this works

class Dog extends Animal {

    Sound getSound() {
        noiseService.bark()
    }

}

I didn't have to put anything in resources.groovy for the Dog or Animal classes

James Kleeh
  • 12,094
  • 5
  • 34
  • 61
0

If you want to instantiate Dog, just do this:

noiseService(com.whatever.DogNoiseService) { bean ->
}

animal(com.thepound.Dog) { bean ->
    noiseService = ref("noiseService")
}
raffian
  • 31,267
  • 26
  • 103
  • 174
  • I have probably a dozen classes that inherit from `Animal`. This would mean I would have to duplicate this for every single one? – James Kleeh Oct 17 '13 at 20:46
  • @JamesKleeh If you declare them as Grails services (in grails-app/service) there's no need to do that manually. –  Oct 17 '13 at 20:50
  • Yes I realize that, however I don't feel the work being done here fits the model of services. There isn't any persistence in any of the classes. – James Kleeh Oct 17 '13 at 20:53
  • @SérgioMichels I usually take this approach, albeit my service configs are more complicated, and there's lot's of them, I prefer to centralize the wiring in `resources.groovy` – raffian Oct 17 '13 at 20:58
  • @JamesKleeh You don't have to, I was simply following your original approach. I use this method and none of my services use persistence; a service is whatever you define as a service. You can use convention over configuration and let grails figure it out without manually wiring the beans, but when things don't work it's harder to figure out why: http://grails.org/doc/latest/guide/gettingStarted.html#conventionOverConfiguration – raffian Oct 17 '13 at 21:02
  • Ok if I move my subclasses into `grails-app/service` do I also need to move the abstract class? – James Kleeh Oct 17 '13 at 21:15
  • Make sure the abstract class is somewhere on the source or library path, but if you're using convention over configuation, you should try and collocate the services in `grails-app/service` – raffian Oct 17 '13 at 21:22
  • @raffian I tend to prefer creating a grails plugin intead of resources.groovy. –  Oct 17 '13 at 21:39