I am trying to get All the instances subclass of trait(interface). This trait have multiple implementation which are provided third party users.
Is this possible to get All the instances subclasses without explicit binding because I don't have control, Implementation provided by third party users. ?
I already saw the same question in which you need to bind explicitly.
Code sample:
import javax.inject.Inject
import com.google.inject._
import scala.collection.JavaConversions._
object DemoApp extends App {
val injector = Guice.createInjector(new AllImplModule)
injector.getInstance(classOf[Action]).perform()
}
class Action @Inject()(impls: List[B]) {
def perform() = {
impls.foreach(b => println(b.name))
}
}
class AllImplModule extends AbstractModule {
override def configure() = {
bind(classOf[Action]).asEagerSingleton()
}
@Provides
@Singleton
def getAllImpls(injector: Injector): List[B] = {
injector.getAllBindings().keySet().collect {
case key: Key[_] if (classOf[B].isAssignableFrom(key.getTypeLiteral().getRawType())) =>
injector.getInstance(key).asInstanceOf[B]
}.toList
}
}
trait B {
def name: String
}
class C1 extends B {
override def name: String = "C1"
}
class C2 extends B {
override def name: String = "C2"
}
This is not working. Any help would be appreciated!
You can inject multiple implementations of the trait using guice-multibindings extension.
Add
"com.google.inject.extensions" % "guice-multibindings" % "4.1.0"
to your build.sbt fileIn the Play module define your bindings like this:
In the component when you want to inject your multiple bindings declare the dependency in this way:
Then it should work.
Your example code looks ok. Here is a Scala worksheet that dynamically finds all bound implementations of a certain
abstract class
/trait
Returns: