Reputation: 674
I used to get the application.conf
variable in Play 2.4.x with Play.current.configuration.getString('NAME_HERE')
, and it was working good in class, object and companion object too.
Now, I'm using Play 2.5.4 with Scala in a new project, and I won't use this Play.current
, because it's deprecated, but there is an alternative using DI, like this :
class HomeController @Inject() (configuration: play.api.Configuration) extends Controller {
def config = Action {
Ok(configuration.underlying.getString("db.driver"))
}
}
This DI Injection works like a charm in class, but in this project, I need to get the variable db.driver
in a object? And as far I know, with an object I can't use DI.
Maybe using Guice would help?
Upvotes: 3
Views: 2361
Reputation: 3868
Have you tried
import com.typesafe.config.ConfigFactory
val myConfig = ConfigFactory.load().getString("myConfig.key")
Above approach doesn't require you to convert your object to singleton class.
Upvotes: 1
Reputation: 3353
You can use @Singleton
annotated class instead of object
trait Foo {}
@Singleton
class FooImpl @Inject()(configuration: play.api.Configuration)) extends Foo {
//do whatever you want
}
@Singleton
makes the class singleton.It feels bit awkward because Scala itself natively have syntax object
to create a singleton, But this is the easiest and probably best solution to DI into a singleton.
You also may create the singleton eagerly like the code below.
bind(classOf[Foo]).to(classOf[FooImpl])asEagerSingleton()
for more detail Info, You can look up Google Guice Wiki and Playframework site
EDIT
How you call it is exactly the same as how you DI in Playframework2.5.
class BarController @Inject()(foo: Foo) extends Controller {
//Do whatever you want with Foo
}
Guice basically generates new instance every time you DI, Once you put @Singleton
, Guice use only one instance instead.
DI is for anti-high coupling.So when you want to use a class you defined from another class,You need to DI otherwise the classes are highly coupled which end up making it harder to code your unit test.
FYI, You can use them outside of Play with this technique.
Create an Instance of class which does DI via Playframework Guice Independently in Scala
Upvotes: 1
Reputation: 8443
You can do
Play.current.configuration
however that will (probably) no longer be possible with Play 2.6.
Ideally, however, you would pass the configuration in as a parameter to that method of the object or, use a class instead of an object.
What I somtimes do to migrate 'from object to class':
class MyComponent @Inject() (config: Configuration) {
// here goes everything nice
def doStuff = ???
}
object MyComponent {
@deprecated("Inject MyComponent")
def doStuff = {
val instance = Play.current.injector.instanceOf[MyComponent]
instance.doStuff
}
}
This way, you're not breaking existing code while all users of your methods can slowly migrate to using classes.
Upvotes: -1