dublintech
dublintech

Reputation: 17785

Injecting different services in Grails

Is it possible, to have two services implement the same interface and to decide at runtime what service to to inject for the interface in Grails?

For example

MyAService implements MyInterface {
...
}

MyBService implements MyInterface {
...
}

Other services then just have a reference to MyInterface and you decide based on config setting or whatever what service to inject?

Upvotes: 3

Views: 689

Answers (2)

Isammoc
Isammoc

Reputation: 893

In my project, I use the resources.groovy

if(myconf == "A") {
  myInterfaceService = ref('myAService')
} else {
  myInterfaceService = ref('myBService')
}

But I think it is a bad practice because both myAService and myBService are instancied even if only one is really used.

I would rather have only one service as grails service and different different implementations will lie in the src directories and then either:

  • use the resources.groovy to fill the service with correct implementation
  • or make my service implements afterPropertiesSet from InitializingBean interface

Upvotes: 2

Burt Beckwith
Burt Beckwith

Reputation: 75671

Grails uses auto-inject by name for convention-based injection like def fooService, and artifacts like services are auto-registered at startup. You have more control if you configure a bean and its dependencies in resources.groovy, and can use Groovy code to apply logic.

But I'd keep things simple and do the work in BootStrap.groovy. Add a public field (e.g. def myService) or a private field and a setter (e.g. void setMyService(service) { this.myService = service } in the destination class. Then in BootStrap, dependency-inject all of the possible candidates and manually inject the correct one. Something like

class BootStrap {

   def myAService
   def myBService
   def theDestinationBean

   def init = { servletContext ->
      if (<some condition>) {
         theDestinationBean.myService = myAService
      }
      else {
         theDestinationBean.myService = myBService
      }
   }
}

Since it's Groovy, you probably don't need the interface, but it doesn't hurt and can give you a bit of compile-time safety.

Upvotes: 6

Related Questions