Creating a AbstractModule to inject a dependency for a 3rd party library

Viewed 127

I have a 3rd party library that I am trying to inject the configuration into the constructor. This is what I need to do:

class MyModule(configuration: Configuration) extends AbstractModule {
  override def configure(): Unit = {
     bind(classOf[TwitterApi])
       .to(classOf[MyTwitterApi])
       .asEagerSingleton
  }
}

The constructor of MyTwitterApi doesn't take a Play.api.Configuration but a typesafe.config.Config

class MyTwitterApi(config: Config) ...

So I need to do pass configuration.underlying to my constructor, how is this possible using DI in this AbstractModule?

I need this instance to be a singleton also.

2 Answers

You can use provider to setup your module with eagerSingleton

import com.google.inject.{AbstractModule, Provider}

class MyModule(configuration: Configuration) extends AbstractModule {
  override def configure(): Unit = {
     val twitterApiProvider: Provider[TwitterApi] = 
       () => new MyTwitterApi(configuration.underlying)
     bind(classOf[TwitterApi])
       .toProvider(twitterApiProvider)
       .asEagerSingleton
  }
}

You can find a working example with sample classes at - https://scastie.scala-lang.org/sarveshseri/ujwvJJNnTpiWDqdkBJQoFw/2

I think you want something like this:

class MyModule(configuration: Configuration) extends AbstractModule {
  override def configure(): Unit = {
     val myTwitterApiInstance = new MyTwitterApi(configuration.underlying)
     bind(classOf[TwitterApi])
       .toInstance(myTwitterApiInstance)
  }
}

Or another approach would be to provide a binding for Config but if your MyTwitterApi doesn't have @Inject annotation this won't help.

Related