Reputation: 17785
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
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:
resources.groovy
to fill the service with correct implementationafterPropertiesSet
from InitializingBean
interfaceUpvotes: 2
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